/*++ Copyright (c) 1990 Microsoft Corporation Module Name: misc.c Abstract: Control routines (etc.) for testing MISC class SMBs: Echo Query FS Information Set FS Information Query Disk Information Author: Chuck Lenzmeier (chuckl) 23-Feb-1990 David Treadwell (davidtr) Revision History: --*/ #define INCLUDE_SMB_MISC #define toint(c) ( (c) >= '0' && (c) <= '9' ? (c) - '0' : \ (c) >= 'a' && (c) <= 'f' ? (c) - 'a' + 10 : \ (c) >= 'A' && (c) <= 'F' ? (c) - 'A' + 10 : -1 ) #include "usrv.h" NTSTATUS MakeEchoSmb( IN OUT PDESCRIPTOR Redir, IN OUT PVOID Buffer, IN OUT PVOID ForcedParams OPTIONAL, IN PID_SELECTIONS IdSelections, IN PID_VALUES IdValues, OUT PULONG SmbSize, IN CLONG EchoSize, IN CLONG EchoCount ) // // *** Note that this SMB maker does NOT follow the standard prototype // for SMB makers, and thus cannot be called from the main redir // loop. // { PSMB_HEADER Header; PREQ_ECHO Params; NTSTATUS status; Header = (PSMB_HEADER)Buffer; if ( ForcedParams == NULL ) { Params = (PREQ_ECHO)(Header + 1); status = MakeSmbHeader( Redir, Header, SMB_COM_ECHO, IdSelections, IdValues ); if ( !NT_SUCCESS(status) ) { return status; } } else { Params = (PREQ_ECHO)ForcedParams; } Params->WordCount = 1; SmbPutUshort( &Params->EchoCount, (USHORT)EchoCount ); SmbPutUshort( &Params->ByteCount, (USHORT)EchoSize ); *SmbSize = GET_ANDX_OFFSET( Header, Params, REQ_ECHO, EchoSize ); return STATUS_SUCCESS; } // MakeEchoSmb NTSTATUS VerifyEcho( IN OUT PDESCRIPTOR Redir, IN PVOID ForcedParams OPTIONAL, IN PID_SELECTIONS IdSelections, IN OUT PID_VALUES IdValues, IN PVOID Buffer, IN OUT PCLONG EchoSize ) // // *** Note that this SMB verifier does NOT follow the standard prototype // for SMB verifiers, and thus cannot be called from the main redir // loop. // { PSMB_HEADER Header; PRESP_ECHO Params; NTSTATUS status; Header = (PSMB_HEADER)(Buffer); if ( ForcedParams == NULL ) { Params = (PRESP_ECHO)(Header + 1); status = VerifySmbHeader( Redir, IdSelections, IdValues, Header, SMB_COM_ECHO ); if( !NT_SUCCESS(status) ) { return status; } } else { Params = (PRESP_ECHO)ForcedParams; } if ( (CLONG)SmbGetUshort( &Params->ByteCount ) > *EchoSize ) { IF_SMB_ERROR_PRINT { printf( "Echo size too large. Expected %ld, received %ld\n", *EchoSize, SmbGetUshort( &Params->ByteCount ) ); } SMB_ERROR_BREAK; IF_SMB_ERROR_QUIT_TEST return STATUS_UNSUCCESSFUL; } //*EchoSize = Params->ByteCount; return STATUS_SUCCESS; } // VerifyEcho NTSTATUS EchoController( IN PDESCRIPTOR Redir, IN PSZ DebugString, IN PVOID Unused, IN UCHAR SubCommand, IN PID_SELECTIONS IdSelections, IN PID_VALUES IdValues, OUT PULONG Unused2 ) { NTSTATUS status; LARGE_INTEGER startTime, endTime, elapsedTime, elapsedMs; LARGE_INTEGER magic10000 = { 0xe219652c, 0xd1b71758 }; ULONG i, j, k; LONG iterations = -1; ULONG interval = 10; ULONG echoSize = 32; ULONG echoCount = 1; ULONG smbSize; SHORT argc; CLONG argPtr; Unused, SubCommand, Unused2; // prevent compiler warnings argc = (SHORT)(Redir->argc - 1); argPtr = 1; while ( (argc > 0) && (*Redir->argv[argPtr] == '-') ) { PSZ arg = Redir->argv[argPtr] + 1; switch ( *arg ) { case 'e': // echo count case 'E': echoCount = atol( arg + 1 ); break; case 'i': // iteration count case 'I': iterations = atol( arg + 1 ); break; case 'r': // timing report interval case 'R': interval = atol( arg + 1 ); break; case 's': // echo data size case 'S': echoSize = atol( arg + 1 ); break; default: printf( "EchoController: Invalid switch %s\n", arg-1 ); DbgBreakPoint( ); return STATUS_INVALID_PARAMETER; } argc--; argPtr++; } if ( echoSize > (ULONG)(Redir->MaxBufferSize - 100) ) { echoSize = Redir->MaxBufferSize - 100; } if ( echoSize == 0 ) { printf( "EchoController: invalid echo size %ld\n", echoSize ); DbgBreakPoint( ); return STATUS_INVALID_PARAMETER; } printf( "Echoing using %ld user bytes, echo count %ld, iterations %ld\n", echoSize, echoCount, iterations ); for ( i = iterations; iterations < 0 ? TRUE : (BOOLEAN)(i > 0); i -= interval ) { (VOID)NtQuerySystemTime( (PLARGE_INTEGER)&startTime ); for ( j = interval; j > 0; j-- ) { status = MakeEchoSmb( Redir, Redir->Data[0], NULL, IdSelections, IdValues, &smbSize, echoSize, echoCount ); if ( !NT_SUCCESS(status) ) { return status; } status = SendAndReceiveSmb( Redir, DebugString, smbSize, 0, 1 ); if ( !NT_SUCCESS(status) ) { return status; } status = VerifyEcho( Redir, NULL, IdSelections, IdValues, Redir->Data[1], (PCLONG)&echoSize ); if ( !NT_SUCCESS(status) ) { return status; } for ( k = echoCount - 1; k > 0; k-- ) { status = ReceiveSmb( Redir, DebugString, 1 ); if ( !NT_SUCCESS(status) ) { return status; } status = VerifyEcho( Redir, NULL, IdSelections, IdValues, Redir->Data[1], (PCLONG)&echoSize ); if ( !NT_SUCCESS(status) ) { return status; } } // for ( k = echoCount - 1; k > 0; k-- ) } // for ( j = interval; j > 0; j-- ) (VOID)NtQuerySystemTime( (PLARGE_INTEGER)&endTime ); elapsedTime.QuadPart = endTime.QuadPart - startTime.QuadPart; elapsedMs = RtlExtendedMagicDivide( elapsedTime, magic10000, 13 ); printf( "Echoes sent/received %ld, elapsed ms %ld, rate %ld msgs/sec\n", interval, elapsedMs.LowPart, interval * 1000 / elapsedMs.LowPart ); } return STATUS_SUCCESS; } // EchoController NTSTATUS MakeSendSmb( IN OUT PDESCRIPTOR Redir, IN OUT PVOID Buffer, IN OUT PVOID ForcedParams OPTIONAL, IN UCHAR AndXCommand, IN PID_SELECTIONS IdSelections, IN PID_VALUES IdValues, OUT PULONG SmbSize ) { NTSTATUS status; PCHAR readBuffer; PCHAR outBuffer = Buffer; ULONG i; STRING smbFileName; UNICODE_STRING unicodeSmbFileName; OBJECT_ATTRIBUTES objectAttributes; IO_STATUS_BLOCK ioStatusBlock; HANDLE fileHandle; AndXCommand, IdSelections, IdValues, ForcedParams; if ( Redir->argc < 2 ) { printf( "usage: send smbfile\n" ); } smbFileName.Buffer = Redir->argv[1]; smbFileName.Length = (SHORT)strlen( Redir->argv[1] ); status = RtlAnsiStringToUnicodeString( &unicodeSmbFileName, &smbFileName, TRUE ); ASSERT( NT_SUCCESS(status) ); InitializeObjectAttributes( &objectAttributes, &unicodeSmbFileName, OBJ_CASE_INSENSITIVE, NULL, NULL ); status = NtOpenFile( &fileHandle, FILE_READ_DATA | SYNCHRONIZE, &objectAttributes, &ioStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT ); RtlFreeUnicodeString( &unicodeSmbFileName ); if ( !NT_SUCCESS(status) ) { printf( "Error opening file %Z: %X\n", &smbFileName, status ); return status; } readBuffer = malloc( 8192 ); if ( readBuffer == NULL ) { NtClose( fileHandle ); return STATUS_INSUFFICIENT_RESOURCES; } status = NtReadFile( fileHandle, NULL, NULL, NULL, &ioStatusBlock, readBuffer, 8192, NULL, NULL ); if ( !NT_SUCCESS(status) ) { printf( "Error reading smb file %Z: %X\n", &smbFileName, status ); return status; } for ( i = 0; i < ioStatusBlock.Information && readBuffer[i] != '!'; i++ ) { if ( isxdigit( readBuffer[i] ) ) { *outBuffer = (CHAR)( toint( readBuffer[i] ) << 4 ); i++; *outBuffer++ |= toint( readBuffer[i] ); i++; } else if ( readBuffer[i] == '#' ) { while ( readBuffer[++i] != '\n' ); } } *SmbSize = outBuffer - (PCHAR)Buffer; free( readBuffer ); NtClose( fileHandle ); return STATUS_SUCCESS; } // MakeSendSmb NTSTATUS VerifySend( IN OUT PDESCRIPTOR Redir, IN PVOID ForcedParams OPTIONAL, IN UCHAR AndXCommand, IN PID_SELECTIONS IdSelections, IN OUT PID_VALUES IdValues, OUT PULONG SmbSize, IN PVOID Buffer ) { PSMB_HEADER Header; PVOID Params; NTSTATUS status; PCHAR readBuffer; PCHAR outBuffer = Buffer; ULONG i; ULONG j; STRING smbFileName; UNICODE_STRING unicodeSmbFileName; OBJECT_ATTRIBUTES objectAttributes; IO_STATUS_BLOCK ioStatusBlock; HANDLE fileHandle; BOOLEAN printedHeader = FALSE; ULONG testSmbSize; AndXCommand, SmbSize; // prevent compiler warnings Header = (PSMB_HEADER)(Buffer); if ( ForcedParams == NULL ) { Params = Header + 1; status = VerifySmbHeader( Redir, IdSelections, IdValues, Header, SMB_COM_NO_ANDX_COMMAND ); if( !NT_SUCCESS(status) ) { return status; } } else { Params = ForcedParams; } smbFileName.Buffer = Redir->argv[1]; smbFileName.Length = (SHORT)strlen( Redir->argv[1] ); status = RtlAnsiStringToUnicodeString( &unicodeSmbFileName, &smbFileName, TRUE ); ASSERT( NT_SUCCESS(status) ); InitializeObjectAttributes( &objectAttributes, &unicodeSmbFileName, OBJ_CASE_INSENSITIVE, NULL, NULL ); status = NtOpenFile( &fileHandle, FILE_READ_DATA | SYNCHRONIZE, &objectAttributes, &ioStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT ); RtlFreeUnicodeString( &unicodeSmbFileName ); if ( !NT_SUCCESS(status) ) { printf( "Error opening file %Z: %X\n", &smbFileName, status ); return status; } readBuffer = malloc( 8192 ); if ( readBuffer == NULL ) { NtClose( fileHandle ); return STATUS_INSUFFICIENT_RESOURCES; } status = NtReadFile( fileHandle, NULL, NULL, NULL, &ioStatusBlock, readBuffer, 8192, NULL, NULL ); if ( !NT_SUCCESS(status) ) { printf( "Error reading smb file %Z: %X\n", &smbFileName, status ); return status; } for ( i = 0; i < ioStatusBlock.Information && readBuffer[i] != '!'; i++ ); for ( i++, j = 0; i < ioStatusBlock.Information; i++ ) { if ( isxdigit( readBuffer[i] ) ) { readBuffer[j] = (CHAR)( toint( readBuffer[i] ) << 4 ); i++; readBuffer[j] |= toint( readBuffer[i] ); i++; j++; } else if ( readBuffer[i] == '#' ) { while ( readBuffer[++i] != '\n' ); } } testSmbSize = j; *SmbSize = Redir->Iosb[1].Information; if ( *SmbSize != testSmbSize ) { printf( "Expected size %ld, actual size %ld\n", testSmbSize, *SmbSize ); } for ( i = 0, j = 0; i < testSmbSize && j < *SmbSize; i++, j++ ) { if ( readBuffer[i] != outBuffer[j] ) { if ( !printedHeader ) { printf( "Offset\tExpect\tActual\n" ); printedHeader = TRUE; } printf( " %ld\t %02lx\t %02lx\n", j, (readBuffer[i] & 0xFF), (outBuffer[j] & 0xFF) ); } } free( readBuffer ); NtClose( fileHandle ); return STATUS_SUCCESS; } // VerifySendSmb NTSTATUS QueryFSInformation( IN OUT PDESCRIPTOR Redir, IN PSZ DebugString, IN PVOID Unused, IN UCHAR SubCommand, IN PID_SELECTIONS IdSelections, IN PID_VALUES IdValues, OUT PULONG Unused2 ) { NTSTATUS status; USHORT infoLevel; USHORT setup; CLONG inSetupCount; CLONG outSetupCount; PVOID parameters; CLONG inParameterCount; CLONG outParameterCount; PVOID data = NULL; CLONG inDataCount = 0; CLONG outDataCount; PREQ_QUERY_FS_INFORMATION request; Unused, Unused2, SubCommand; if ( Redir->argc < 3 ) { printf( "Usage: qfs X: infolevel\n" ); return STATUS_INVALID_PARAMETER; } infoLevel = (USHORT)atol( Redir->argv[2] ); inSetupCount = 1; outSetupCount = 0; setup = TRANS2_QUERY_FS_INFORMATION; inParameterCount = sizeof(REQ_QUERY_FS_INFORMATION); outParameterCount = 0; parameters = malloc( inParameterCount ); request = parameters; switch( infoLevel ) { case SMB_INFO_ALLOCATION: outDataCount = sizeof(FSALLOCATE); break; case SMB_INFO_VOLUME: outDataCount = sizeof(FSINFO) + 20; // +20 for extra label space break; case SMB_QUERY_FS_LABEL_INFO: outDataCount = sizeof( FILE_FS_LABEL_INFORMATION ) + 20*2; break; case SMB_QUERY_FS_VOLUME_INFO: outDataCount = sizeof( FILE_FS_VOLUME_INFORMATION ) + 20*2; break; case SMB_QUERY_FS_SIZE_INFO: outDataCount = sizeof( FILE_FS_SIZE_INFORMATION ); break; case SMB_QUERY_FS_DEVICE_INFO: outDataCount = sizeof( FILE_FS_DEVICE_INFORMATION ); break; case SMB_QUERY_FS_ATTRIBUTE_INFO: outDataCount = sizeof( FILE_FS_ATTRIBUTE_INFORMATION ) + 100; break; } data = malloc( outDataCount ); SmbPutUshort( &request->InformationLevel, infoLevel ); status = SendAndReceiveTransaction( Redir, DebugString, IdSelections, IdValues, SMB_COM_TRANSACTION2, &setup, inSetupCount, &outSetupCount, "", 0, parameters, inParameterCount, &outParameterCount, data, inDataCount, &outDataCount ); if ( !NT_SUCCESS(status) ) { goto exit; } if ( outSetupCount != 0 ) { printf( "QueryFSInformation: bad return setup count: %ld\n", outSetupCount ); status = STATUS_UNSUCCESSFUL; goto exit; } if ( outParameterCount != 0 ) { printf( "QueryFSInformation:: bad return parameter count: %ld\n", outParameterCount ); status = STATUS_UNSUCCESSFUL; goto exit; } // // Print results. // if ( infoLevel == SMB_INFO_ALLOCATION ) { PFSALLOCATE fsAllocate = data; printf( "idFileSystem: 0x%lx\n", SmbGetAlignedUlong( &fsAllocate->idFileSystem ) ); printf( "cSectorUnit: %ld\n", SmbGetAlignedUlong( &fsAllocate->cSectorUnit ) ); printf( "cUnit: %ld\n", SmbGetAlignedUlong( &fsAllocate->cUnit ) ); printf( "cUnitAvail: %ld\n", SmbGetAlignedUlong( &fsAllocate->cUnitAvail ) ); printf( "cbSector: %ld\n", SmbGetAlignedUshort( &fsAllocate->cbSector ) ); } else if (infoLevel == SMB_INFO_VOLUME) { PFSINFO fsInfo = data; printf( "Serial number: %4lx-%4lx; Label: %s\n", SmbGetAlignedUlong( &fsInfo->ulVsn ) & 0xffff, SmbGetAlignedUlong( &fsInfo->ulVsn ) >> 16, fsInfo->vol.szVolLabel ); } else if (infoLevel == SMB_QUERY_FS_LABEL_INFO ) { PFILE_FS_LABEL_INFORMATION fsInfo = data; UNICODE_STRING label; label.Buffer = fsInfo->VolumeLabel; label.Length = (USHORT)SmbGetUlong( &fsInfo->VolumeLabelLength ); printf( "Volume label: %wZ\n", &label ); } else if (infoLevel == SMB_QUERY_FS_VOLUME_INFO ) { PFILE_FS_VOLUME_INFORMATION fsInfo = data; UNICODE_STRING label; LARGE_INTEGER time; TIME_FIELDS timeFields; label.Buffer = fsInfo->VolumeLabel; label.Length = (USHORT)SmbGetUlong( &fsInfo->VolumeLabelLength ); time.HighPart = SmbGetUlong( &fsInfo->VolumeCreationTime.HighPart ); time.LowPart = SmbGetUlong( &fsInfo->VolumeCreationTime.LowPart ); RtlTimeToTimeFields(&time, &timeFields ); printf ("Volume label: %wZ, created %d/%d/%d, serial number %ld\n" "%s support objects\n", &label, timeFields.Month, timeFields.Day, timeFields.Year, SmbGetUlong( &fsInfo->VolumeSerialNumber ), fsInfo->SupportsObjects ? "does" : "does not" ); } else if (infoLevel == SMB_QUERY_FS_SIZE_INFO ) { PFILE_FS_SIZE_INFORMATION fsInfo = data; printf ("Total allocation units = 0x%lx%08lx\n", SmbGetUlong( &fsInfo->TotalAllocationUnits.HighPart ), SmbGetUlong( &fsInfo->TotalAllocationUnits.LowPart ) ); printf ("Available allocation units = 0x%lx%08lx\n", SmbGetUlong( &fsInfo->AvailableAllocationUnits.HighPart ), SmbGetUlong( &fsInfo->AvailableAllocationUnits.LowPart ) ); printf ("Sectors per allocation unit = %ld\n", SmbGetUlong( &fsInfo->SectorsPerAllocationUnit ) ); printf ("Bytes per sector = %ld\n", SmbGetUlong( &fsInfo->BytesPerSector ) ); } else if (infoLevel == SMB_QUERY_FS_DEVICE_INFO ) { PFILE_FS_DEVICE_INFORMATION fsInfo = data; printf ("Device type = 0x%lx, characteristic = 0x%lx\n", SmbGetUlong( &fsInfo->DeviceType ), SmbGetUlong( &fsInfo->Characteristics ) ); } else if (infoLevel == SMB_QUERY_FS_ATTRIBUTE_INFO ) { PFILE_FS_ATTRIBUTE_INFORMATION fsInfo = data; UNICODE_STRING fsName; fsName.Buffer = fsInfo->FileSystemName; fsName.Length = (USHORT)SmbGetUlong( &fsInfo->FileSystemNameLength ); printf( "FS attributes 0x%lx\n", SmbGetUlong( &fsInfo->FileSystemAttributes ) ); printf( "FS max component name length %d\n", SmbGetUlong( &fsInfo->MaximumComponentNameLength ) ); printf( "FS name: %wZ\n", &fsName ); } status = STATUS_PENDING; exit: free( parameters ); if ( data != NULL ) { free( data ); } return status; } // QueryFSInformation NTSTATUS SetFSInformation( IN OUT PDESCRIPTOR Redir, IN PSZ DebugString, IN PVOID Unused, IN UCHAR SubCommand, IN PID_SELECTIONS IdSelections, IN PID_VALUES IdValues, OUT PULONG Unused2 ) { NTSTATUS status; USHORT setup; CLONG inSetupCount; CLONG outSetupCount; PVOID parameters; CLONG inParameterCount; CLONG outParameterCount; PVOID data = NULL; CLONG inDataCount; CLONG outDataCount = 0; PREQ_SET_FS_INFORMATION request; PVOLUMELABEL volumeLabel; Unused, Unused2, SubCommand; if ( Redir->argc < 3 ) { printf( "Usage: sfs X: volumelabel\n" ); return STATUS_INVALID_PARAMETER; } inSetupCount = 1; outSetupCount = 0; setup = TRANS2_SET_FS_INFORMATION; inParameterCount = sizeof(REQ_SET_FS_INFORMATION); outParameterCount = 0; parameters = malloc( inParameterCount ); request = parameters; inDataCount = strlen( Redir->argv[2] ) + 2; data = malloc( inDataCount ); SmbPutUshort( &request->InformationLevel, 2 ); volumeLabel = (PVOLUMELABEL)data; volumeLabel->cch = (UCHAR)strlen( Redir->argv[2] ); RtlMoveMemory( volumeLabel->szVolLabel, Redir->argv[2], volumeLabel->cch ); status = SendAndReceiveTransaction( Redir, DebugString, IdSelections, IdValues, SMB_COM_TRANSACTION2, &setup, inSetupCount, &outSetupCount, "", 0, parameters, inParameterCount, &outParameterCount, data, inDataCount, &outDataCount ); if ( !NT_SUCCESS(status) ) { goto exit; } if ( outSetupCount != 0 ) { printf( "SetFSInformation: bad return setup count: %ld\n", outSetupCount ); status = STATUS_UNSUCCESSFUL; goto exit; } if ( outParameterCount != 0 ) { printf( "SetFSInformation: bad return parameter count: %ld\n", outParameterCount ); status = STATUS_UNSUCCESSFUL; goto exit; } free( parameters ); if ( data != NULL ) { free( data ); } return STATUS_PENDING; exit: free( parameters ); if ( data != NULL ) { free( data ); } return status; } // SetFSInformation NTSTATUS MakeQueryInformationDiskSmb( IN OUT PDESCRIPTOR Redir, IN OUT PVOID Buffer, IN OUT PVOID ForcedParams OPTIONAL, IN UCHAR AndXCommand, IN PID_SELECTIONS IdSelections, IN PID_VALUES IdValues, OUT PULONG SmbSize ) { PSMB_HEADER Header; PREQ_QUERY_INFORMATION_DISK Params; NTSTATUS status; AndXCommand; // prevent compiler warnings Header = (PSMB_HEADER)Buffer; if ( ForcedParams == NULL ) { Params = (PREQ_QUERY_INFORMATION_DISK)(Header + 1); status = MakeSmbHeader( Redir, Header, SMB_COM_QUERY_INFORMATION_DISK, IdSelections, IdValues ); if ( !NT_SUCCESS(status) ) { return status; } } else { Params = (PREQ_QUERY_INFORMATION_DISK)(ForcedParams); } Params->WordCount = 0; SmbPutUshort( &Params->ByteCount, (USHORT)(FileDefs[IdSelections->Fid].Name.Length + 1) ); RtlMoveMemory( Params->Buffer, FileDefs[IdSelections->Fid].Name.Buffer, FileDefs[IdSelections->Fid].Name.Length + 1 ); *SmbSize = GET_ANDX_OFFSET( Header, Params, REQ_QUERY_INFORMATION_DISK, SmbGetUshort( &Params->ByteCount ) ); return STATUS_SUCCESS; } // MakeQueryInformationDiskSmb NTSTATUS VerifyQueryInformationDisk( IN OUT PDESCRIPTOR Redir, IN PVOID ForcedParams OPTIONAL, IN UCHAR AndXCommand, IN PID_SELECTIONS IdSelections, IN OUT PID_VALUES IdValues, OUT PULONG SmbSize, IN PVOID Buffer ) { PSMB_HEADER Header; PRESP_QUERY_INFORMATION_DISK Params; NTSTATUS status; AndXCommand, SmbSize; // prevent compiler warnings Header = (PSMB_HEADER)(Buffer); if ( ForcedParams == NULL ) { Params = (PRESP_QUERY_INFORMATION_DISK)(Header + 1); status = VerifySmbHeader( Redir, IdSelections, IdValues, Header, SMB_COM_QUERY_INFORMATION_DISK ); if( !NT_SUCCESS(status) ) { return status; } } else { Params = (PRESP_QUERY_INFORMATION_DISK)ForcedParams; } printf( "Total Units: %ld\n", SmbGetUshort( &Params->TotalUnits ) ); printf( "Blocks Per Unit: %ld\n", SmbGetUshort( &Params->BlocksPerUnit ) ); printf( "Block Size: %ld\n", SmbGetUshort( &Params->BlockSize ) ); printf( "Free Units: %ld\n", SmbGetUshort( &Params->FreeUnits ) ); return STATUS_SUCCESS; } // VerifyQueryInformationDisk NTSTATUS ThreadSleep( IN PDESCRIPTOR Redir, IN PSZ DebugString, IN PVOID Unused1, IN UCHAR Time, IN PID_SELECTIONS IdSelections, IN PID_VALUES IdValues, OUT PULONG Unused2 ) { LARGE_INTEGER delayTime; ULONG ms; if (Time > 0) { printf( "Sleeping for %lu tenths of a second\n", Time ); ms = Time * 100; delayTime.QuadPart = Int32x32To64( ms, -10000 ); NtDelayExecution( TRUE, (PLARGE_INTEGER)&delayTime ); } Redir, DebugString, Unused1, IdSelections, IdValues, Unused2; return STATUS_SUCCESS; } NTSTATUS QuerySecurityController( IN OUT PDESCRIPTOR Redir, IN PSZ DebugString, IN PVOID Unused, IN UCHAR SubCommand, IN PID_SELECTIONS IdSelections, IN PID_VALUES IdValues, OUT PULONG Unused2 ) { NTSTATUS status; USHORT setup; CLONG inSetupCount; CLONG outSetupCount; REQ_QUERY_SECURITY_DESCRIPTOR *request, parameters; CLONG inParameterCount; CLONG outParameterCount; PVOID data = NULL; CLONG inDataCount = 0; CLONG outDataCount = 1000; Unused, Unused2, SubCommand; data = malloc( 1000 ); if ( data == NULL) { goto exit; } inSetupCount = 0; outSetupCount = 0; inParameterCount = sizeof(REQ_QUERY_SECURITY_DESCRIPTOR); outParameterCount = sizeof(RESP_QUERY_SECURITY_DESCRIPTOR); request = ¶meters; SmbPutUshort( &request->Fid, IdValues->Fid[IdSelections->Fid] ); SmbPutUshort( &request->Reserved, 0 ); SmbPutUlong( &request->SecurityInformation, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION ); status = SendAndReceiveTransaction( Redir, DebugString, IdSelections, IdValues, SMB_COM_NT_TRANSACT, &setup, inSetupCount, &outSetupCount, "", NT_TRANSACT_QUERY_SECURITY_DESC, ¶meters, inParameterCount, &outParameterCount, data, inDataCount, &outDataCount ); if ( !NT_SUCCESS(status) ) { goto exit; } if ( outSetupCount != 0 ) { printf( "QuerySecurity: bad return setup count: %ld\n", outSetupCount ); status = STATUS_UNSUCCESSFUL; goto exit; } if ( outParameterCount != sizeof( RESP_QUERY_SECURITY_DESCRIPTOR ) ) { printf( "QuerySecurity: Bad return parameter count: %ld\n", outParameterCount ); status = STATUS_UNSUCCESSFUL; goto exit; } status = STATUS_PENDING; exit: if ( data != NULL ) { free( data ); } return status; } // QuerySecurity NTSTATUS SetSecurityController( IN OUT PDESCRIPTOR Redir, IN PSZ DebugString, IN PVOID Unused, IN UCHAR SubCommand, IN PID_SELECTIONS IdSelections, IN PID_VALUES IdValues, OUT PULONG Unused2 ) { NTSTATUS status; USHORT setup; CLONG inSetupCount; CLONG outSetupCount; REQ_SET_SECURITY_DESCRIPTOR parameters, *request; CLONG inParameterCount; CLONG outParameterCount; PVOID data = NULL; CLONG inDataCount = 1000; CLONG outDataCount = 0; Unused, Unused2, SubCommand; data = malloc( 1000 ); if ( data == NULL) { goto exit; } request = ¶meters; inSetupCount = 0; outSetupCount = 0; inParameterCount = sizeof(REQ_SET_SECURITY_DESCRIPTOR); outParameterCount = 0; SmbPutUshort( &request->Fid, IdValues->Fid[IdSelections->Fid] ); SmbPutUshort( &request->Reserved, 0 ); SmbPutUlong( &request->SecurityInformation, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION ); status = SendAndReceiveTransaction( Redir, DebugString, IdSelections, IdValues, SMB_COM_NT_TRANSACT, &setup, inSetupCount, &outSetupCount, "", NT_TRANSACT_QUERY_SECURITY_DESC, ¶meters, inParameterCount, &outParameterCount, data, inDataCount, &outDataCount ); if ( !NT_SUCCESS(status) ) { goto exit; } if ( outSetupCount != 0 ) { printf( "SetSecurity: bad return setup count: %ld\n", outSetupCount ); status = STATUS_UNSUCCESSFUL; goto exit; } if ( outParameterCount != 0 ) { printf( "SetSecurity: Bad return parameter count: %ld\n", outParameterCount ); status = STATUS_UNSUCCESSFUL; goto exit; } status = STATUS_PENDING; exit: if ( data != NULL ) { free( data ); } return status; } // QuerySecurity