2025-04-27 07:49:33 -04:00

485 lines
16 KiB
C

#define _UNICODE
#define UNICODE
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <ntmsapi.h>
#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);
}
}