#define _UNICODE #define UNICODE #include #include #include #include #define ADD_ACE_MASK_BITS 1 #define REMOVE_ACE_MASK_BITS 2 #define DELETE_ACE 3 NTMS_GUID RsmNullGuid = { 0 }; DbgShowGuid(NTMS_GUID *g) { int i; printf("\n { "); for (i = 0; i < sizeof(NTMS_GUID); i++){ printf("%x ", (unsigned int)(((unsigned char *)g)[i])); } printf("}\n"); } DWORD SetPoolDACL( HANDLE hSession, NTMS_GUID gMediaPool, DWORD dwSubAuthority, DWORD dwAction, DWORD dwMask) { PSID psidAccount; PSECURITY_DESCRIPTOR psdRePoolSd; SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY; DWORD dwRetCode, dwSizeTry; BOOL OK; DWORD i, result = ERROR_INVALID_SID; ACCESS_ALLOWED_ACE *pAce; // Get a SID for the well known, domain-relative account or group if (AllocateAndInitializeSid( &ntauth, 2, SECURITY_BUILTIN_DOMAIN_RID, dwSubAuthority, 0, 0, 0, 0, 0, 0, &psidAccount ) == 0){ result = GetLastError(); } else { // Get the security descriptor for the pool dwSizeTry = 5; OK = FALSE; for(;;) { psdRePoolSd = (PSID)malloc(dwSizeTry); if (psdRePoolSd){ dwRetCode = GetNtmsObjectSecurity( hSession, &gMediaPool, NTMS_MEDIA_POOL, DACL_SECURITY_INFORMATION, psdRePoolSd, dwSizeTry, &dwSizeTry); if (dwRetCode == ERROR_SUCCESS){ OK = TRUE; break; } else { free(psdRePoolSd); if (dwRetCode == ERROR_INSUFFICIENT_BUFFER){ // loop and try again with new buffer size } else { break; } } } else { break; } } if (OK){ PACL paclDis; BOOL bDaclPresent, bDaclDefaulted; //Get a pointer to the DACL OK = GetSecurityDescriptorDacl(psdRePoolSd, &bDaclPresent, &paclDis, &bDaclDefaulted); if (OK){ // Go through the DACL and change the mask of the ACE that matches the SID for (i = 0; i < paclDis->AceCount; i++){ OK = GetAce(paclDis, i, (LPVOID *)&pAce); if (OK){ if (EqualSid(psidAccount, &pAce->SidStart)){ printf("\n SetPoolDACL: found SID, current mask = %xh \n", pAce->Mask); if (dwAction == ADD_ACE_MASK_BITS){ pAce->Mask |= dwMask; printf("\n SetPoolDACL: added mask bits %xh to create mask %xh \n", dwMask, pAce->Mask); } else if (dwAction == REMOVE_ACE_MASK_BITS){ pAce->Mask &= ~dwMask; printf("\n SetPoolDACL: removed mask bits %xh to create mask %xh \n", dwMask, pAce->Mask); } else if (dwAction == DELETE_ACE){ DeleteAce(paclDis, i); } } } } if (OK){ dwRetCode = SetNtmsObjectSecurity( hSession, &gMediaPool, NTMS_MEDIA_POOL, DACL_SECURITY_INFORMATION, psdRePoolSd); result = ERROR_SUCCESS; } } } FreeSid(psidAccount); } return result; } BOOL SetupMediaPool(HANDLE hSession, NTMS_GUID gMediaPoolId) { DWORD dwStatus; BOOL result = FALSE; NTMS_OBJECTINFORMATION oiInfoBuffer; oiInfoBuffer.dwSize = sizeof(oiInfoBuffer); oiInfoBuffer.dwType = NTMS_MEDIA_POOL; dwStatus = GetNtmsObjectInformation(hSession, &gMediaPoolId, &oiInfoBuffer); if (dwStatus == ERROR_SUCCESS){ oiInfoBuffer.Info.MediaPool.AllocationPolicy = NTMS_ALLOCATE_FROMSCRATCH; dwStatus = SetNtmsObjectInformation(hSession, &gMediaPoolId, &oiInfoBuffer); if (dwStatus == ERROR_SUCCESS){ DWORD errNum; // Change the permissions on the pool errNum = SetPoolDACL( hSession, gMediaPoolId, DOMAIN_ALIAS_RID_USERS, REMOVE_ACE_MASK_BITS, NTMS_MODIFY_ACCESS | NTMS_CONTROL_ACCESS); if (errNum == ERROR_SUCCESS){ result = TRUE; } else { printf("\n SetupMediaPool: SetPoolDACL failed with %d=%xh.\n", dwStatus, dwStatus); } } else { printf("\n SetupMediaPool: SetNtmsObjectInformation failed with %d=%xh.\n", dwStatus, dwStatus); } } else { printf("\n SetupMediaPool: GetNtmsObjectInformation failed with %d=%xh.\n", dwStatus, dwStatus); } return result; } BOOL EnumerateObjectType( HANDLE hSession, LPNTMS_GUID gContainer, DWORD dwType, LPNTMS_GUID *gList, DWORD *dwCount) { DWORD dwRetCode; BOOL result = FALSE; // Enumerate the libraries *dwCount = 5; while (TRUE){ *gList = (LPNTMS_GUID)malloc((*dwCount)*sizeof(NTMS_GUID)); if (*gList){ dwRetCode = EnumerateNtmsObject(hSession, gContainer, *gList, dwCount, dwType, 0); if (dwRetCode == ERROR_INSUFFICIENT_BUFFER){ // retry with new size in *dwCount free(*gList); continue; } else if (dwRetCode == ERROR_SUCCESS){ result = TRUE; break; } else { free(*gList); break;; } } else { printf("\n malloc failed \n"); break; } } return result; } // Find the first online library BOOL MyFindLibrary(HANDLE hSession, NTMS_GUID *gLibID, DWORD *dwRetCode) { DWORD dwSize, i; NTMS_GUID *gLibList = NULL; NTMS_OBJECTINFORMATION oiLibraryInfo; BOOL result = FALSE; // Enumerate the libraries if (EnumerateObjectType(hSession, NULL, NTMS_LIBRARY, &gLibList, &dwSize)){ // Find the first online library oiLibraryInfo.dwSize = sizeof(oiLibraryInfo); oiLibraryInfo.dwType = NTMS_LIBRARY; for (i = 0; i < dwSize; i++){ DWORD errCode; errCode = GetNtmsObjectInformation( hSession, &gLibList[i], &oiLibraryInfo); if (errCode == ERROR_SUCCESS){ if (oiLibraryInfo.Info.Library.LibraryType == NTMS_LIBRARYTYPE_ONLINE){ *gLibID = gLibList[i]; result = TRUE; break; } else if (oiLibraryInfo.Info.Library.LibraryType == NTMS_LIBRARYTYPE_STANDALONE){ /* * This may be a 'standalone' changer drive or a CD/DVD-ROM drive. * We only want to deal with it if it's a changer drive. * * BUGBUG - what's the right check for this ?? */ if (oiLibraryInfo.Info.Library.LibrarySupportsDriveCleaning){ *gLibID = gLibList[i]; result = TRUE; break; } } } else { printf("\n MyFindLibrary: GetNtmsObjectInformation failed with %xh.\n", errCode); break; } } free(gLibList); } else { printf("\n MyFindLibrary: EnumerateObjectType failed\n"); } *dwRetCode = result ? ERROR_SUCCESS : ERROR_NOT_FOUND; return result; } BOOL MyFindMediaType(HANDLE hSession, NTMS_GUID *gMediaID, DWORD *dwRetCode) { NTMS_GUID gLibrary; BOOL result = FALSE; // Get the GUID for the library if (MyFindLibrary(hSession, &gLibrary, dwRetCode)){ NTMS_GUID *gTypeList = NULL; NTMS_OBJECTINFORMATION oiMediaTypeInfo; DWORD dwSize, i; // Get the list of media type GUIDS in the library if (EnumerateObjectType(hSession, &gLibrary, NTMS_MEDIA_TYPE, &gTypeList, &dwSize)){ // Go through the guid list and find a rewritable media type oiMediaTypeInfo.dwSize = sizeof(oiMediaTypeInfo); oiMediaTypeInfo.dwType = NTMS_MEDIA_TYPE; for (i = 0; i < dwSize; i++){ DWORD errCode; errCode = GetNtmsObjectInformation( hSession, &gTypeList[i], &oiMediaTypeInfo); if (errCode == ERROR_SUCCESS){ if ((oiMediaTypeInfo.Info.MediaType.ReadWriteCharacteristics == NTMS_MEDIARW_REWRITABLE) || (oiMediaTypeInfo.Info.MediaType.ReadWriteCharacteristics == NTMS_MEDIARW_WRITEONCE) || (oiMediaTypeInfo.Info.MediaType.ReadWriteCharacteristics == NTMS_MEDIARW_READONLY)){ *gMediaID = gTypeList[i]; result = TRUE; break; } } else { printf("\n GetNtmsObjectInformation failed in MyFindMediaType with status %xh.\n", errCode); } } free(gTypeList); } else { printf("\n MyFindMediaType: EnumerateObjectType failed\n"); } } *dwRetCode = result ? ERROR_SUCCESS : ERROR_NOT_FOUND; return result; } int __cdecl main() { HANDLE hSession; hSession = OpenNtmsSession(L"", L"DemoApp", 0); if (hSession == INVALID_HANDLE_VALUE){ printf("\n OpenNtmsSession failed\n"); } else { NTMS_GUID gMediaType; DWORD tmpRet; if (MyFindMediaType(hSession, &gMediaType, &tmpRet)){ NTMS_GUID gMediaPool = RsmNullGuid; DWORD dwStatus; printf("\n OpenNtmsSession succeeded\n"); dwStatus = CreateNtmsMediaPool( hSession, L"API_Sample_Pool", &gMediaType, NTMS_OPEN_ALWAYS, NULL, &gMediaPool); if (dwStatus == ERROR_SUCCESS){ if (SetupMediaPool(hSession, gMediaPool)){ NTMS_GUID gMediaID = RsmNullGuid; DWORD dwTimeout = INFINITE; printf("\n CreateNtmsMediaPool succeeded\n"); DbgShowGuid(&gMediaPool); dwStatus = AllocateNtmsMedia( hSession, &gMediaPool, NULL, &gMediaID, NTMS_ALLOCATE_ERROR_IF_UNAVAILABLE, // BUGBUG NTMS_ALLOCATE_NEW, 0, // don't wait NULL); if (dwStatus == ERROR_SUCCESS){ NTMS_GUID gDriveID; printf("\n AllocateNtmsMedia succeeded\n"); printf("\n MOUNTING drive ... "); dwStatus = MountNtmsMedia( hSession, &gMediaID, &gDriveID, // BUGBUG - want specific drive - how to get guid ? 1, NTMS_MOUNT_ERROR_NOT_AVAILABLE, NTMS_PRIORITY_NORMAL, INFINITE, NULL); if (dwStatus == ERROR_SUCCESS){ NTMS_OBJECTINFORMATION oiDriveInfo; oiDriveInfo.dwSize = sizeof(oiDriveInfo); oiDriveInfo.dwType = NTMS_DRIVE; dwStatus = GetNtmsObjectInformation( hSession, &gDriveID, &oiDriveInfo); if (dwStatus == ERROR_SUCCESS){ HANDLE hDrive; printf("\n drive name is '%s'\n", oiDriveInfo.Info.Drive.szDeviceName); hDrive = CreateFile(oiDriveInfo.Info.Drive.szDeviceName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDrive == INVALID_HANDLE_VALUE){ int errNum = GetLastError(); printf("\n CreateFile failed with %d=%xh. \n", errNum, errNum); } else { char s[20]; /* * PAUSE until user hits key */ printf("\n DRIVE '%s' mounted and opened, hit any key to continue ...", oiDriveInfo.Info.Drive.szDeviceName); gets(s); printf(" ... closing drive ... \n"); CloseHandle(hDrive); } } else { printf("\n GetNtmsObjectInformation failed with %d=%xh. \n", dwStatus, dwStatus); } dwStatus = DismountNtmsMedia( hSession, &gMediaID, 1, 0); if (dwStatus == ERROR_SUCCESS){ printf("\n DismountNtmsMedia succeeded\n"); } else { printf("\n DismountNtmsMedia failed with %d=%xh. \n", dwStatus, dwStatus); } } else { printf("\n MountNtmsMedia failed with %d=%xh. \n", dwStatus, dwStatus); } DeallocateNtmsMedia( hSession, (LPNTMS_GUID)&gMediaID, 0); } else { printf("\n AllocateNtmsMedia failed with %d=%xh. \n", dwStatus, dwStatus); } } DeleteNtmsMediaPool(hSession, &gMediaPool); } else { printf("\n CreateNtmsMediaPool failed with %d=%xh\n", dwStatus, dwStatus); } } else { printf("\n MyFindMediaType failed \n"); } CloseNtmsSession(hSession); } }