VOID SepServerSpawnClientProcess(VOID) { RTL_USER_PROCESS_INFORMATION ProcessInformation; STRING ImagePathName, ProgramName; UNICODE_STRING UnicodeImagePathName, UnicodeProgramName; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; RtlInitString( &ProgramName, "\\SystemRoot\\Bin\\utlpcqos.exe" ); Status = RtlAnsiStringToUnicodeString( &UnicodeProgramName, &ProgramName, TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) ); RtlInitString( &ImagePathName, "utlpcqos.exe"); Status = RtlAnsiStringToUnicodeString( &UnicodeImagePathName, &ImagePathName, TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) ); Status = RtlCreateProcessParameters( &ProcessParameters, &ImagePathName, //UNICODEFIX &UnicodeImagePathName, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); SEASSERT_SUCCESS(Status); Status = RtlCreateUserProcess( &ProgramName, // UNICODEFIX &UnicodeProgramName, ProcessParameters, // ProcessParameters NULL, // ProcessSecurityDescriptor NULL, // ThreadSecurityDescriptor NtCurrentProcess(), // ParentProcess FALSE, // InheritHandles NULL, // DebugPort NULL, // ExceptionPort &ProcessInformation // ProcessInformation ); SEASSERT_SUCCESS(Status); Status = NtResumeThread( ProcessInformation.Thread, NULL ); SEASSERT_SUCCESS(Status); RtlDestroyProcessParameters( ProcessParameters ); RtlFreeUnicodeString( &UnicodeProgramName ); RtlFreeUnicodeString( &UnicodeImagePathName ); }
NTSTATUS openfile ( IN PHANDLE filehandle, IN PUCHAR BasePath, IN PUCHAR Name ) { ANSI_STRING AscBasePath, AscName; UNICODE_STRING UniPathName, UniName; NTSTATUS status; OBJECT_ATTRIBUTES ObjA; IO_STATUS_BLOCK IOSB; UCHAR StringBuf[500]; // // Build name // UniPathName.Buffer = (PWCHAR)StringBuf; UniPathName.Length = 0; UniPathName.MaximumLength = sizeof( StringBuf ); RtlInitString(&AscBasePath, BasePath); RtlAnsiStringToUnicodeString( &UniPathName, &AscBasePath, FALSE ); RtlInitString(&AscName, Name); RtlAnsiStringToUnicodeString( &UniName, &AscName, TRUE ); RtlAppendUnicodeStringToString (&UniPathName, &UniName); InitializeObjectAttributes( &ObjA, &UniPathName, OBJ_CASE_INSENSITIVE, 0, 0 ); // // open file // status = NtOpenFile ( filehandle, // return handle SYNCHRONIZE | FILE_READ_DATA, // desired access &ObjA, // Object &IOSB, // io status block FILE_SHARE_READ | FILE_SHARE_WRITE, // share access FILE_SYNCHRONOUS_IO_ALERT // open options ); RtlFreeUnicodeString (&UniName); return status; }
BOOLEAN OvsCompareString(PVOID string1, PVOID string2) { /* * Not a super-efficient string compare since we walk over the strings * twice: to initialize, and then to do the comparison. */ STRING str1, str2; RtlInitString(&str1, string1); RtlInitString(&str2, string2); return RtlEqualString(&str1, &str2, FALSE); }
void Initialize (IN USHORT Length_In) { OBJECT_ATTRIBUTES ObjectAttributes; STRING DeviceName; USHORT j; char TestPkt[] = "WOW 32 Simulator on NT\n\r"; RtlInitString(&DeviceName, "\\Device\\Serial1"); // // set attributes // ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); ObjectAttributes.RootDirectory = NULL; ObjectAttributes.ObjectName = &DeviceName; ObjectAttributes.Attributes = OBJ_INHERIT; ObjectAttributes.SecuriAR) SECONDBYTE(Size); TransmitPkt[10] = EOT; if (!Xceive((USHORT)(Size+5), 11)) { DbgPrint ("Sim32GetVDMPSZPointer.....Unsuccessful \a\a\n"); return NULL; } RtlMoveMemory(Ptr, &ReceivePkt[4], Size); } else {
BOOLEAN SidTranslation( PSID Sid, PSTRING AccountName ) // AccountName is expected to have a large maximum length { if (RtlEqualSid(Sid, WorldSid)) { RtlInitString( AccountName, "WORLD"); return(TRUE); } if (RtlEqualSid(Sid, LocalSid)) { RtlInitString( AccountName, "LOCAL"); return(TRUE); } if (RtlEqualSid(Sid, NetworkSid)) { RtlInitString( AccountName, "NETWORK"); return(TRUE); } if (RtlEqualSid(Sid, BatchSid)) { RtlInitString( AccountName, "BATCH"); return(TRUE); } if (RtlEqualSid(Sid, InteractiveSid)) { RtlInitString( AccountName, "INTERACTIVE"); return(TRUE); } if (RtlEqualSid(Sid, LocalSystemSid)) { RtlInitString( AccountName, "SYSTEM"); return(TRUE); } if (RtlEqualSid(Sid, LocalManagerSid)) { RtlInitString( AccountName, "LOCAL MANAGER"); return(TRUE); } if (RtlEqualSid(Sid, LocalAdminSid)) { RtlInitString( AccountName, "LOCAL ADMIN"); return(TRUE); } return(FALSE); }
VOID Mkdir( IN PCHAR String ) { NTSTATUS Status; HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; IO_STATUS_BLOCK IoStatus; LARGE_INTEGER AllocationSize; // // Get the filename // simprintf("Mkdir ", 0); simprintf(String, 0); simprintf("\n", 0); // // Create the new directory // AllocationSize = LiFromLong( 4 ); RtlInitString( &NameString, String ); InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL ); if (!NT_SUCCESS(Status = NtCreateFile( &FileHandle, SYNCHRONIZE, &ObjectAttributes, &IoStatus, &AllocationSize, 0L, 0L, FILE_CREATE, WriteThrough | FILE_DIRECTORY_FILE, (PVOID)NULL, 0L ))) { CreateFileError( Status , String ); return; } // // Now close the directory // if (!NT_SUCCESS(Status = NtClose( FileHandle ))) { CloseError( Status ); } // // And return to our caller // return; }
PVOID GetSectionDllFuncAddr(IN PCHAR lpFunctionName, IN PVOID BaseAddress) { PVOID functionAddress = NULL; PIMAGE_DOS_HEADER dosheader; PIMAGE_OPTIONAL_HEADER opthdr; PIMAGE_EXPORT_DIRECTORY pExportTable; PDWORD arrayOfFunctionAddresses; PDWORD arrayOfFunctionNames; PWORD arrayOfFunctionOrdinals; DWORD Base; STRING ntFunctionName, ntFunctionNameSearch; PCHAR functionName; DWORD functionOrdinal; ULONG x; ASSERT(lpFunctionName&&BaseAddress); dosheader = (PIMAGE_DOS_HEADER)BaseAddress; opthdr =(PIMAGE_OPTIONAL_HEADER) ((PBYTE)BaseAddress+dosheader->e_lfanew+24); pExportTable =(PIMAGE_EXPORT_DIRECTORY)((PBYTE)BaseAddress + opthdr->DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); // now we can get the exported functions, but note we convert from RVA to address arrayOfFunctionAddresses = (PDWORD)( (PBYTE)BaseAddress + pExportTable->AddressOfFunctions); arrayOfFunctionNames = (PDWORD)( (PBYTE)BaseAddress + pExportTable->AddressOfNames); arrayOfFunctionOrdinals = (PWORD)( (PBYTE)BaseAddress + pExportTable->AddressOfNameOrdinals); Base = pExportTable->Base; RtlInitString(&ntFunctionNameSearch, lpFunctionName); for (x = 0; x < pExportTable->NumberOfFunctions; x++) { functionName = (PCHAR)( (PBYTE)BaseAddress + arrayOfFunctionNames[x]); RtlInitString(&ntFunctionName, functionName); functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1; // always need to add base, -1 as array counts from 0 // this is the funny bit. you would expect the function pointer to simply be arrayOfFunctionAddresses[x]... // oh no... thats too simple. it is actually arrayOfFunctionAddresses[functionOrdinal]!! if (RtlCompareString(&ntFunctionName, &ntFunctionNameSearch, TRUE) == 0) { functionAddress = (PBYTE)BaseAddress + arrayOfFunctionAddresses[functionOrdinal]; break; } } return functionAddress; }
PCSR_THREAD CsrConnectToUser( VOID ) { static BOOLEAN (*ClientThreadSetupRoutine)(VOID) = NULL; NTSTATUS Status; ANSI_STRING DllName; UNICODE_STRING DllName_U; STRING ProcedureName; HANDLE UserClientModuleHandle; PTEB Teb; PCSR_THREAD Thread; BOOLEAN fConnected; if (ClientThreadSetupRoutine == NULL) { RtlInitAnsiString(&DllName, "user32"); Status = RtlAnsiStringToUnicodeString(&DllName_U, &DllName, TRUE); ASSERT(NT_SUCCESS(Status)); Status = LdrGetDllHandle( UNICODE_NULL, NULL, &DllName_U, (PVOID *)&UserClientModuleHandle ); RtlFreeUnicodeString(&DllName_U); if ( NT_SUCCESS(Status) ) { RtlInitString(&ProcedureName,"ClientThreadSetup"); Status = LdrGetProcedureAddress( UserClientModuleHandle, &ProcedureName, 0L, (PVOID *)&ClientThreadSetupRoutine ); ASSERT(NT_SUCCESS(Status)); } } try { fConnected = ClientThreadSetupRoutine(); } except (EXCEPTION_EXECUTE_HANDLER) { fConnected = FALSE; } if (!fConnected) { IF_DEBUG { DbgPrint("CSRSS: CsrConnectToUser failed\n"); } return NULL; }
VOID TestChild( VOID ) { NTSTATUS Status; STRING DirectoryName; HANDLE DirectoryHandle; OBJECT_ATTRIBUTES ObjectAttributes; Status = STATUS_SUCCESS; DbgPrint( "Entering Object Manager User Mode Child Test Program\n" ); RtlInitString( &DirectoryName, "\\ExclusiveDir" ); InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = NtOpenDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to open %Z directory object (%X) [OK]\n", &DirectoryName, Status ); } InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, OBJ_CASE_INSENSITIVE | OBJ_EXCLUSIVE, NULL, NULL ); Status = NtOpenDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to open %Z directory object (%X) [OK]\n", &DirectoryName, Status ); } DbgPrint( "Exiting Object Manager User Mode Child Test Program with Status = %X\n", Status ); }
BOOLEAN OpenMailslot( PSZ Name, PHANDLE Handle ) { STRING ansiString; UNICODE_STRING nameString; NTSTATUS status; OBJECT_ATTRIBUTES objectAttributes; IO_STATUS_BLOCK ioStatusBlock; RtlInitString(&ansiString, Name ); RtlOemStringToUnicodeString(&nameString, &ansiString, TRUE); // // Open the mailslot // InitializeObjectAttributes( &objectAttributes, &nameString, OBJ_CASE_INSENSITIVE, NULL, NULL ); printf( "Attempting to open mailslot \"%wZ\"\n", &nameString ); status = NtOpenFile ( Handle, FILE_WRITE_DATA | SYNCHRONIZE, &objectAttributes, &ioStatusBlock, FILE_SHARE_WRITE | FILE_SHARE_READ, 0L ); printf( "Status = %x\n", status ); RtlFreeUnicodeString(&nameString); return ( (BOOLEAN) NT_SUCCESS( status ) ); }
/****************************************************************************** * Driver unload handler * ******************************************************************************/ static VOID DDKAPI my_unload(PDRIVER_OBJECT DriverObject) { ANSI_STRING SymbolicLinkNameA; UNICODE_STRING SymbolicLinkNameW; DbgPrint("DriverUnload called\r\n"); PsSetCreateProcessNotifyRoutine(create_process_watcher, TRUE); PsRemoveLoadImageNotifyRoutine(load_image_watcher); RtlInitString(&SymbolicLinkNameA, MY_DOSDEVICE_NAME); RtlAnsiStringToUnicodeString(&SymbolicLinkNameW, &SymbolicLinkNameA, TRUE); IoDeleteSymbolicLink(&SymbolicLinkNameW); IoDeleteDevice(DriverObject->DeviceObject); for (int i = 0; i < ENT_CNT; ++i) if(g_proc_table[i].pid) DbgPrint("Registered process stays: %d\r\n", g_proc_table[i].pid); }
static NTSTATUS v2v_get_remote_state_internal(xenbus_transaction_t xbt, struct v2v_channel *channel, enum v2v_endpoint_state *state) { NTSTATUS status; char *raw; STRING s1, s2; XM_ASSERT(channel != NULL); XM_ASSERT(state != NULL); *state = v2v_state_unknown; status = v2v_xenstore_readv_string(&raw, xbt, channel->remote_prefix, "state", NULL); if (!NT_SUCCESS(status)) return status; RtlInitString(&s1, raw); if (RtlCompareString(&s1, v2v_make_cs(&s2, "unready"), FALSE) == 0) *state = v2v_state_unready; else if (RtlCompareString(&s1, v2v_make_cs(&s2, "listening"), FALSE) == 0) *state = v2v_state_listening; else if (RtlCompareString(&s1, v2v_make_cs(&s2, "connected"), FALSE) == 0) *state = v2v_state_connected; else if (RtlCompareString(&s1, v2v_make_cs(&s2, "disconnecting"), FALSE) == 0) *state = v2v_state_disconnecting; else if (RtlCompareString(&s1, v2v_make_cs(&s2, "disconnected"), FALSE) == 0) *state = v2v_state_disconnected; else if (RtlCompareString(&s1, v2v_make_cs(&s2, "crashed"), FALSE) == 0) *state = v2v_state_crashed; ExFreePoolWithTag(raw, V2V_TAG); return (*state != v2v_state_unknown ? STATUS_SUCCESS : STATUS_DATA_ERROR); }
BOOL giveMePac(PCSTR Username, PSID DomainSid, DWORD UserId, KerberosTime *AuthTime, DWORD SignatureType, EncryptionKey * SignatureKey, _octet1 *pac) { BOOL status = FALSE; KERB_VALIDATION_INFO validationInfo = {0}; STRING user; kull_m_kerberos_asn1_helper_util_UTCKerberosTimeToFileTime(AuthTime, &validationInfo.LogonTime); KIWI_NEVERTIME(&validationInfo.LogoffTime); KIWI_NEVERTIME(&validationInfo.KickOffTime); KIWI_NEVERTIME(&validationInfo.PasswordLastSet); KIWI_NEVERTIME(&validationInfo.PasswordCanChange); KIWI_NEVERTIME(&validationInfo.PasswordMustChange); pac->length = 0; pac->value = NULL; RtlInitString(&user, Username); if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&validationInfo.EffectiveName, &user, TRUE))) { validationInfo.LogonDomainId = (PISID) DomainSid; validationInfo.UserId = UserId; validationInfo.UserAccountControl = USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT; validationInfo.PrimaryGroupId = defaultGroups[0].RelativeId; validationInfo.GroupCount = ARRAYSIZE(defaultGroups); validationInfo.GroupIds = defaultGroups; if(kuhl_m_pac_validationInfo_to_PAC(&validationInfo, SignatureType, (PPACTYPE *) &pac->value, (DWORD *) &pac->length)) { kprintf(" * PAC generated\n"); if(status = NT_SUCCESS(kuhl_m_pac_signature((PPACTYPE) pac->value, pac->length, SignatureType, SignatureKey ? SignatureKey->keyvalue.value : NULL, SignatureKey ? SignatureKey->keyvalue.length : 0))) kprintf(" * PAC \"\"\"signed\"\"\"\n"); else LocalFree(pac->value); } RtlFreeUnicodeString(&validationInfo.EffectiveName); } return status; }
VOID Create( IN PCHAR FileName, IN ULONG FileTime, IN ULONG FileCount ) { NTSTATUS Status; HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; IO_STATUS_BLOCK IoStatus; LARGE_INTEGER AllocationSize; LARGE_INTEGER ByteOffset; ULONG Count; ULONG Pattern[3]; // // Get the filename // simprintf("Create ", 0); simprintf(FileName, 0); simprintf("\n", 0); // // Create the new file // AllocationSize = LiFromUlong( FileCount * 4 ); RtlInitString( &NameString, FileName ); InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL ); if (!NT_SUCCESS(Status = NtCreateFile( &FileHandle, FILE_WRITE_DATA | SYNCHRONIZE, &ObjectAttributes, &IoStatus, &AllocationSize, FILE_ATTRIBUTE_NORMAL, 0L, FILE_SUPERSEDE, WriteThrough, (PVOID)NULL, 0L ))) { CreateFileError( Status , FileName ); return; } // // The main loop writes out the test pattern our test pattern // is <FileTime> <FileSize> <Count> where count is the current // iteration count for the current test pattern output. // Pattern[0] = FileTime; Pattern[1] = FileCount; for (Count = 0; Count < FileCount; Count += 1) { Pattern[2] = Count; ByteOffset = LiFromUlong( Count * 3 * 4 ); if (!NT_SUCCESS(Status = NtWriteFile( FileHandle, (HANDLE)NULL, (PIO_APC_ROUTINE)NULL, (PVOID)NULL, &IoStatus, Pattern, 3 * 4, &ByteOffset, (PULONG) NULL ))) { WriteFileError( Status ); return; } if (!NT_SUCCESS(Status = NtWaitForSingleObject(FileHandle, TRUE, NULL))) { WaitForSingleObjectError( Status ); return; } // // check how the write turned out // CheckIoStatus( &IoStatus, 3 * 4, FALSE ); if (!NT_SUCCESS(IoStatus.Status)) { IoStatusError( IoStatus.Status ); break; } } // // Now close the file // if (!NT_SUCCESS(Status = NtClose( FileHandle ))) { CloseError( Status ); } // // And return to our caller // return; }
NTSTATUS ApfCreateDataSection(PAPFCONTROL *ApfDataSectionPointer) { NTSTATUS Status; STRING ApfDataSectionName; UNICODE_STRING ApfDataSectionUnicodeName; OBJECT_ATTRIBUTES ObjectAttributes; LARGE_INTEGER AllocationSize; ULONG ViewSize; PAPFCONTROL DataSectionPointer; // // Initialize object attributes // RtlInitString(&ApfDataSectionName, DATA_SEC_NAME); Status = RtlAnsiStringToUnicodeString( &ApfDataSectionUnicodeName, &ApfDataSectionName, TRUE); if (NT_SUCCESS(Status)) { InitializeObjectAttributes( &ObjectAttributes, &ApfDataSectionUnicodeName, OBJ_OPENIF | OBJ_CASE_INSENSITIVE, NULL, &SecDescriptor); } #ifdef ERRORDBG else { KdPrint (("WAP: RtlAnsiStringToUnicodeString() failed in " "ApfCreateDataSection, %lx\n", Status)); } #endif AllocationSize.HighPart = 0; // Need a slot to account for calibration data // AllocationSize.LowPart = (API_COUNT + 1) * sizeof(APFDATA); // Create a read-write section // Status = NtCreateSection(&ApfDataSectionHandle, SECTION_MAP_READ | SECTION_MAP_WRITE, &ObjectAttributes, &AllocationSize, PAGE_READWRITE, SEC_COMMIT, NULL); if (NT_SUCCESS(Status)) { ViewSize = AllocationSize.LowPart; DataSectionPointer = NULL; // Map the section // Status = NtMapViewOfSection(ApfDataSectionHandle, MyProcess, (PVOID *)&DataSectionPointer, 0, AllocationSize.LowPart, NULL, &ViewSize, ViewUnmap, 0L, PAGE_READWRITE); #ifdef ERRORDBG if (!NT_SUCCESS(Status)) { KdPrint (("WAP: NtMapViewOfSection() failed in ApfCreateDataSection," " %lx\n", Status)); } #endif *ApfDataSectionPointer = DataSectionPointer; } #ifdef ERRORDBG else { KdPrint (("WAP: NtCreateSection() failed in ApfCreateDataSection " "%lx\n", Status)); } #endif return(Status); } /* ApfCreateDataSection () */
void ApfInitDll () { NTSTATUS Status; DWORD ulInitElapsedTime; SHORT sInitTimerHandle; DWORD ARGS64; #ifdef CALIBDBG SHORT sTimerHandle; ULONG ulElapsedTime; #endif #ifdef ERRORDBG DWORD Error; #endif int i; STRING DataSemName; UNICODE_STRING DataSemUnicodeName; OBJECT_ATTRIBUTES DataSemAttributes; // Create public share security descriptor for all the named objects // Status = RtlCreateSecurityDescriptor ( &SecDescriptor, SECURITY_DESCRIPTOR_REVISION1 ); #ifdef ERRORDBG if (!NT_SUCCESS(Status)) { KdPrint (("WAP: RtlCreateSecurityDescriptor falied - 0x%lx\n", Status)); } #endif Status = RtlSetDaclSecurityDescriptor ( &SecDescriptor, // SecurityDescriptor TRUE, // DaclPresent NULL, // Dacl FALSE // DaclDefaulted ); #ifdef ERRORDBG if (!NT_SUCCESS(Status)) { KdPrint (("WAP: RtlSetDaclSecurityDescriptor falied - 0x%lx\n", Status)); } #endif // Create sections for data and api arrays // if ( NT_SUCCESS(ApfCreateDataSection(&ApfControl)) ) { // Leave room for control flag // ApfData = (PAPFDATA)(ApfControl+1); // Initialization for semaphore creation // RtlInitString(&DataSemName, DATA_SEM_NAME); Status = RtlAnsiStringToUnicodeString( &DataSemUnicodeName, &DataSemName, TRUE); if (NT_SUCCESS(Status)) { InitializeObjectAttributes( &DataSemAttributes, &DataSemUnicodeName, OBJ_OPENIF | OBJ_CASE_INSENSITIVE, NULL, &SecDescriptor); } // Create semaphores // Status = NtCreateSemaphore( &hDataSem, SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE | SYNCHRONIZE, &DataSemAttributes, 1L, 1L); #ifdef ERRORDBG if (!NT_SUCCESS(Status)) { KdPrint (("WAP: Data semaphore creation falied %lx\n", Status)); } #endif // Get semaphores // Status = NtWaitForSingleObject(hDataSem,FALSE,NULL); #ifdef ERRORDBG if (!NT_SUCCESS(Status)) { KdPrint (("WAP: Could not wait for Dsemaphore in ApfInitDll, %lx\n", Status)); } #endif // // Do timer calibration if not already done. // if (!ApfControl->fCalibrate) { ApfControl->fCalibrate = TRUE; // // Calibrate time overheads: // we get the minimum time here, to avoid extra time from // interrupts etc. // the tedious approach has two benefits // - duplicate generated code as accurately as possible // - pick up timer overhead, that isn't handled correctly // in timer // NOTE: ApfData[I_CALIBRATE].ulMinTime contains the // timer overhead, while ApfData[I_CALIBRATE].cCalls // contains the number of processess accessing this // DLL. // ApfData[I_CALIBRATE].cCalls = 0L; ApfData[I_CALIBRATE].cTimingErrors = 0L; ApfData[I_CALIBRATE].ulTotalTime = 0L; ApfData[I_CALIBRATE].ulFirstTime = MAX_LONG; ApfData[I_CALIBRATE].ulMaxTime = MAX_LONG; ApfData[I_CALIBRATE].ulMinTime = MAX_LONG; ApfClearData(); TimerOpen(&sInitTimerHandle, MICROSECONDS); #ifdef CALIBDBG // Release semaphore // Status = NtReleaseSemaphore(hDataSem,1,NULL); #ifdef ERRORDBG if (!NT_SUCCESS(Status)) { KdPrint (("WAP: DSemaphore Not Released in ApfInitDll!! %lx\n", Status)); } #endif // // Overhead for all the API wrapper code // Stored in ApfData[I_CALIBRATE].ulMaxTime // Used for debugging - for WOW profiling overhead. // for (i=0; i<NUM_ITRATIONS; i++) { TimerInit(sInitTimerHandle); if (fInitDone == FALSE) { } TimerOpen(&sTimerHandle, MICROSECONDS); TimerInit(sTimerHandle); // // Get the elapsed time // ulElapsedTime = TimerRead(sTimerHandle); ApfRecordInfo(1, ulElapsedTime); TimerClose(sTimerHandle); ulInitElapsedTime = TimerRead(sInitTimerHandle); if ((ulInitElapsedTime < ApfData[I_CALIBRATE].ulMaxTime) && (ulInitElapsedTime > MIN_ACCEPTABLEOVERHEAD)) { ApfData[I_CALIBRATE].ulMaxTime = ulInitElapsedTime; } } // Get semaphores // Status = NtWaitForSingleObject(hDataSem,FALSE,NULL); #ifdef ERRORDBG if (!NT_SUCCESS(Status)) { KdPrint (("WAP: Could not wait for Dsemaphore in ApfInitDll, %lx\n", Status)); } #endif #endif // // Excess overhead for TimerInit() followed by TimerREad() calls // Stored in ApfData[I_CALIBRATE].ulMinTime // Used by all APIs // for (i=0; i<NUM_ITRATIONS; i++) { TimerInit(sInitTimerHandle); ulInitElapsedTime = TimerRead(sInitTimerHandle); if ((ulInitElapsedTime < ApfData[I_CALIBRATE].ulMinTime) && (ulInitElapsedTime > MIN_ACCEPTABLEOVERHEAD)) { ApfData[I_CALIBRATE].ulMinTime = ulInitElapsedTime; } } // // Oerhead for calling cdecl APIs with 64 DWORD arguments // Stored in ApfData[I_CALIBRATE].ulFirstTime // Used by all variable argument cdecl APIs such as wsprintf() // for (i=0; i<NUM_ITRATIONS; i++) { TimerInit(sInitTimerHandle); CalibCdeclApi (ARGS64); ulInitElapsedTime = TimerRead(sInitTimerHandle); if ((ulInitElapsedTime < ApfData[I_CALIBRATE].ulFirstTime) && (ulInitElapsedTime > MIN_ACCEPTABLEOVERHEAD)) { ApfData[I_CALIBRATE].ulFirstTime = ulInitElapsedTime; } } ApfData[I_CALIBRATE].ulFirstTime -= ApfData[I_CALIBRATE].ulMinTime; TimerClose(sInitTimerHandle); } // Increment the number of active processes on this DLL // ApfData[I_CALIBRATE].cCalls++; // Load the module being profiled // hModule=GetModuleHandle(MODULE_NAME); #ifdef ERRORDBG if (hModule==NULL) { Error=GetLastError(); KdPrint (("WAP: Module Handle is null - %lx\n",Error)); } #endif // Release semaphore // Status = NtReleaseSemaphore(hDataSem,1,NULL); #ifdef ERRORDBG if (!NT_SUCCESS(Status)) { KdPrint (("WAP: DSemaphore Not Released in ApfInitDll!! %lx\n", Status)); } #endif fInitDone = TRUE; } #ifdef ERRORDBG else { KdPrint (("WAP: Couldn't create DATA section in ApfInitDll\n")); } #endif } /* ApfInitDll () */
VOID UnloadDriver () { HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; UNICODE_STRING UnicodeString; IO_STATUS_BLOCK IoStatus; NTSTATUS Status; PCHAR DeviceName; DeviceName = &DriveA[0]; RtlInitString( &NameString, DeviceName ); Status = RtlAnsiStringToUnicodeString( &UnicodeString, &NameString, TRUE ); ASSERT( NT_SUCCESS( Status ) ); // // Open the device. // InitializeObjectAttributes( &ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, (HANDLE) NULL, (PSECURITY_DESCRIPTOR) NULL ); Status = NtOpenFile( &FileHandle, FILE_WRITE_DATA | FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &ObjectAttributes, &IoStatus, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT ); RtlFreeUnicodeString( &UnicodeString ); if (!NT_SUCCESS( Status )) { DbgPrint( "unloaddriver: error opening %s for input; error %X\n", DeviceName, Status ); return; } // // Issue the unloaddriver command. // Status = NtDeviceIoControlFile( FileHandle, (HANDLE) NULL, (PIO_APC_ROUTINE) NULL, (PVOID) NULL, &IoStatus, IOCTL_DISK_UNLOAD_DRIVER, NULL, 0L, NULL, 0L ); if (!NT_SUCCESS( Status )) { DbgPrint( "unloaddriver: error on NtDeviceIoControlFile; error %X\n", Status ); } else if (Status != STATUS_SUCCESS) { Status = NtWaitForSingleObject( FileHandle, TRUE, NULL ); if (Status == STATUS_SUCCESS) { if (!NT_SUCCESS( IoStatus.Status )) { if (IoStatus.Status == STATUS_NOT_IMPLEMENTED) { DbgPrint( "unloaddriver: control function not implemented\n" ); } else { DbgPrint( "unloaddriver: error %X\n", IoStatus.Status ); } } } } // // Close the file. // (VOID) NtClose( FileHandle ); return; }
VOID PowerTest () { HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; UNICODE_STRING UnicodeString; IO_STATUS_BLOCK IoStatus; NTSTATUS Status; PCHAR DeviceName; DeviceName = &DriveA[0]; RtlInitString( &NameString, DeviceName ); Status = RtlAnsiStringToUnicodeString( &UnicodeString, &NameString, TRUE ); ASSERT( NT_SUCCESS( Status ) ); // // Open the device. // InitializeObjectAttributes( &ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, (HANDLE) NULL, (PSECURITY_DESCRIPTOR) NULL ); Status = NtOpenFile( &FileHandle, FILE_WRITE_DATA | FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &ObjectAttributes, &IoStatus, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT ); RtlFreeUnicodeString( &UnicodeString ); if (!NT_SUCCESS( Status )) { DbgPrint( "format: error opening %s for input; error %X\n", DeviceName, Status ); return; } // // Issue the I/O control command. // Status = NtDeviceIoControlFile( FileHandle, (HANDLE) NULL, (PIO_APC_ROUTINE) NULL, (PVOID) NULL, &IoStatus, IOCTL_DISK_DBG_POWER_RECOVERY, NULL, 0L, NULL, 0L ); if (!NT_SUCCESS( Status )) { DbgPrint( "PowerTest: error on NtDeviceIoControlFile; error %X\n", Status ); } else if (Status != STATUS_SUCCESS) { Status = NtWaitForSingleObject( FileHandle, TRUE, NULL ); if (Status == STATUS_SUCCESS) { if (!NT_SUCCESS( IoStatus.Status )) { if (IoStatus.Status == STATUS_NOT_IMPLEMENTED) { DbgPrint( "PowerTest: control function not implemented\n" ); } if (IoStatus.Status == STATUS_MEDIA_WRITE_PROTECTED) { DbgPrint( "PowerTest: media is write protected\n" ); } else if (IoStatus.Status == STATUS_DEVICE_NOT_READY) { DbgPrint( "PowerTest: device not ready\n" ); } else { DbgPrint( "PowerTest: error %X\n", IoStatus.Status ); } } } } else { DbgPrint( "On the next read/write operation a power failure will be simulated\n" ); } // // Close the file. // (VOID) NtClose( FileHandle ); return; }
ARC_STATUS CdfsOpen ( IN PCHAR FileName, IN OPEN_MODE OpenMode, IN PULONG FileId ) /*++ Routine Description: This routine searches the root directory for a file matching FileName. If a match is found the dirent for the file is saved and the file is opened. Arguments: FileName - Supplies a pointer to a zero terminated file name. OpenMode - Supplies the mode of the open. FileId - Supplies a pointer to a variable that specifies the file table entry that is to be filled in if the open is successful. Return Value: ESUCCESS is returned if the open operation is successful. Otherwise, an unsuccessful status is returned that describes the reason for failure. --*/ { ARC_STATUS Status; ULONG DeviceId; STRING PathName; STRING Name; BOOLEAN IsDirectory; BOOLEAN SearchSucceeded; // // Save the address of the file table entry, context area, and the device // id in use. // CdfsFileTableEntry = &BlFileTable[*FileId]; CdfsStructureContext = (PCDFS_STRUCTURE_CONTEXT)CdfsFileTableEntry->StructureContext; DeviceId = CdfsFileTableEntry->DeviceId; // // Construct a file name descriptor from the input file name. // RtlInitString( &PathName, FileName ); // // Set the starting directory to be the root directory. // CdfsStructureContext->DirSectorOffset = CdfsStructureContext->RootDirSectorOffset; CdfsStructureContext->DirDiskOffset = CdfsStructureContext->RootDirDiskOffset; CdfsStructureContext->DirSize = CdfsStructureContext->RootDirSize; // // While the path name has some characters in it we'll go through our // loop which extracts the first part of the path name and searches // the current fnode (which must be a directory) for an the entry. // If what we find is a directory then we have a new directory fnode // and simply continue back to the top of the loop. // IsDirectory = TRUE; SearchSucceeded = TRUE; while (PathName.Length > 0 && IsDirectory) { // // Extract the first component. // CdfsFirstComponent( &PathName, &Name ); // // Copy the name into the filename buffer. // CdfsFileTableEntry->FileNameLength = (UCHAR) Name.Length; RtlMoveMemory( CdfsFileTableEntry->FileName, Name.Buffer, Name.Length ); // // Look to see if the file exists. // Status = CdfsSearchDirectory( &Name, &IsDirectory ); if (Status == ENOENT) { SearchSucceeded = FALSE; break; } if (Status != ESUCCESS) { return Status; } } // // If the path name length is not zero then we were trying to crack a path // with an nonexistent (or non directory) name in it. For example, we tried // to crack a\b\c\d and b is not a directory or does not exist (then the path // name will still contain c\d). // if (PathName.Length != 0) { return ENOTDIR; } // // At this point we've cracked the name up to (an maybe including the last // component). We located the last component if the SearchSucceeded flag is // true, otherwise the last component does not exist. If we located the last // component then this is like an open or a supersede, but not a create. // if (SearchSucceeded) { // // Check if the last component is a directory // if (IsDirectory) { // // For an existing directory the only valid open mode is OpenDirectory // all other modes return an error // switch (OpenMode) { case ArcOpenReadOnly: case ArcOpenWriteOnly: case ArcOpenReadWrite: case ArcCreateWriteOnly: case ArcCreateReadWrite: case ArcSupersedeWriteOnly: case ArcSupersedeReadWrite: // // If we reach here then the caller got a directory but didn't // want to open a directory // return EISDIR; case ArcOpenDirectory: // // If we reach here then the caller got a directory and wanted // to open a directory. // CdfsFileTableEntry->u.CdfsFileContext.FileSize = CdfsStructureContext->DirSize; CdfsFileTableEntry->u.CdfsFileContext.DiskOffset = CdfsStructureContext->DirDiskOffset; CdfsFileTableEntry->u.CdfsFileContext.IsDirectory = TRUE; CdfsFileTableEntry->Flags.Open = 1; CdfsFileTableEntry->Flags.Read = 1; CdfsFileTableEntry->Position.LowPart = 0; CdfsFileTableEntry->Position.HighPart = 0; return ESUCCESS; case ArcCreateDirectory: // // If we reach here then the caller got a directory and wanted // to create a new directory // return EACCES; } } // // If we get there then we have an existing file that is being opened. // We can open existing files only read only. // switch (OpenMode) { case ArcOpenReadOnly: // // If we reach here then the user got a file and wanted to open the // file read only // CdfsFileTableEntry->u.CdfsFileContext.FileSize = CdfsStructureContext->DirSize; CdfsFileTableEntry->u.CdfsFileContext.DiskOffset = CdfsStructureContext->DirDiskOffset; CdfsFileTableEntry->u.CdfsFileContext.IsDirectory = FALSE; CdfsFileTableEntry->Flags.Open = 1; CdfsFileTableEntry->Flags.Read = 1; CdfsFileTableEntry->Position.LowPart = 0; CdfsFileTableEntry->Position.HighPart = 0; return ESUCCESS; case ArcOpenWriteOnly: case ArcOpenReadWrite: case ArcCreateWriteOnly: case ArcCreateReadWrite: case ArcSupersedeWriteOnly: case ArcSupersedeReadWrite: // // If we reach here then we are trying to open a read only // device for write. // return EROFS; case ArcOpenDirectory: case ArcCreateDirectory: // // If we reach here then the user got a file and wanted a directory // return ENOTDIR; } } // // If we get here the last component does not exist so we are trying to create // either a new file or a directory. // switch (OpenMode) { case ArcOpenReadOnly: case ArcOpenWriteOnly: case ArcOpenReadWrite: case ArcOpenDirectory: // // If we reach here then the user did not get a file but wanted a file // return ENOENT; case ArcCreateWriteOnly: case ArcSupersedeWriteOnly: case ArcCreateReadWrite: case ArcSupersedeReadWrite: case ArcCreateDirectory: // // If we get hre the user wants to create something. // return EROFS; } // // If we reach here then the path name is exhausted and we didn't // reach a file so return an error to our caller // return ENOENT; }
VOID Directory( IN PCHAR String ) { NTSTATUS Status; HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; IO_STATUS_BLOCK IoStatus; NTSTATUS NtStatus; PFILE_ADIRECTORY_INFORMATION FileInfo; ULONG i; // // Get the filename // simprintf("Directory ", 0); simprintf(String, 0); simprintf("\n", 0); // // Open the file for list directory access // RtlInitString( &NameString, String ); InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL ); if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle, FILE_LIST_DIRECTORY | SYNCHRONIZE, &ObjectAttributes, &IoStatus, FILE_SHARE_READ, WriteThrough | FILE_DIRECTORY_FILE ))) { OpenFileError( Status , String ); return; } // // zero out the buffer so next time we'll recognize the end of data // for (i = 0; i < BUFFERSIZE; i += 1) { Buffer[i] = 0; } // // Do the directory loop // for (NtStatus = NtQueryDirectoryFile( FileHandle, (HANDLE)NULL, (PIO_APC_ROUTINE)NULL, (PVOID)NULL, &IoStatus, Buffer, BUFFERSIZE, FileADirectoryInformation, FALSE, (PSTRING)NULL, TRUE); NT_SUCCESS(NtStatus); NtStatus = NtQueryDirectoryFile( FileHandle, (HANDLE)NULL, (PIO_APC_ROUTINE)NULL, (PVOID)NULL, &IoStatus, Buffer, BUFFERSIZE, FileADirectoryInformation, FALSE, (PSTRING)NULL, FALSE) ) { if (!NT_SUCCESS(Status = NtWaitForSingleObject(FileHandle, TRUE, NULL))) { // NtPartyByNumber(50); WaitForSingleObjectError( Status ); return; } // // Check the Irp for success // if (!NT_SUCCESS(IoStatus.Status)) { break; } // // For every record in the buffer type out the directory information // // // Point to the first record in the buffer, we are guaranteed to have // one otherwise IoStatus would have been No More Files // FileInfo = (PFILE_ADIRECTORY_INFORMATION)&Buffer[0]; while (TRUE) { // // Print out information about the file // simprintf("%8lx ", FileInfo->FileAttributes); simprintf("%8lx/", FileInfo->EndOfFile.LowPart); simprintf("%8lx ", FileInfo->AllocationSize.LowPart); { CHAR Saved; Saved = FileInfo->FileName[FileInfo->FileNameLength]; FileInfo->FileName[FileInfo->FileNameLength] = 0; simprintf(FileInfo->FileName, 0); FileInfo->FileName[FileInfo->FileNameLength] = Saved; } simprintf("\n", 0); // // Check if there is another record, if there isn't then we // simply get out of this loop // if (FileInfo->NextEntryOffset == 0) { break; } // // There is another record so advance FileInfo to the next // record // FileInfo = (PFILE_ADIRECTORY_INFORMATION)(((PUCHAR)FileInfo) + FileInfo->NextEntryOffset); } // // zero out the buffer so next time we'll recognize the end of data // for (i = 0; i < BUFFERSIZE; i += 1) { Buffer[i] = 0; } } // // Now close the file // if (!NT_SUCCESS(Status = NtClose( FileHandle ))) { CloseError( Status ); } // // And return to our caller // return; }
VOID TuneFifoDelay() { HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; UNICODE_STRING UnicodeString; IO_STATUS_BLOCK IoStatus; NTSTATUS Status; PCHAR DeviceName; ULONG Delay; Zero( &Buffer[0], 10 ); DbgPrompt( "Enter number of cycles: ", Buffer, 9 ); Delay = (ULONG) atoi( &(Buffer[0]) ); DeviceName = &DriveA[0]; RtlInitString( &NameString, DeviceName ); Status = RtlAnsiStringToUnicodeString( &UnicodeString, &NameString, TRUE ); ASSERT( NT_SUCCESS( Status ) ); // // Open the device. // InitializeObjectAttributes( &ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, (HANDLE) NULL, (PSECURITY_DESCRIPTOR) NULL ); Status = NtOpenFile( &FileHandle, FILE_WRITE_DATA | FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &ObjectAttributes, &IoStatus, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT ); RtlFreeUnicodeString( &UnicodeString ); if (!NT_SUCCESS( Status )) { DbgPrint( "control: error opening %s for input; error %X\n", DeviceName, Status ); return; } // // Issue the I/O control command // Status = NtDeviceIoControlFile( FileHandle, (HANDLE) NULL, (PIO_APC_ROUTINE) NULL, (PVOID) NULL, &IoStatus, IOCTL_DISK_DBG_FIFO_TUNING, &Delay, (ULONG) sizeof( Delay ), NULL, 0L ); if (!NT_SUCCESS( Status )) { DbgPrint( "control: error on NtDeviceIoControlFile; error %X\n", Status ); } else if (Status != STATUS_SUCCESS) { Status = NtWaitForSingleObject( FileHandle, TRUE, NULL ); if (Status == STATUS_SUCCESS) { if (!NT_SUCCESS( IoStatus.Status )) { if (IoStatus.Status == STATUS_NOT_IMPLEMENTED) { DbgPrint( "control: control function not implemented\n" ); } else { DbgPrint( "control: error %X\n", IoStatus.Status ); } } } } // // Close the file. // (VOID) NtClose( FileHandle ); return; }
VOID GetStatistics () { HANDLE FileHandle; CHAR Indicator; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; UNICODE_STRING UnicodeString; ULONG i; IO_STATUS_BLOCK IoStatus; NTSTATUS Status; PCHAR DeviceName; PFLOPPY_STATISTICS Statistics; DeviceName = &DriveA[0]; RtlInitString( &NameString, DeviceName ); Status = RtlAnsiStringToUnicodeString( &UnicodeString, &NameString, TRUE ); ASSERT( NT_SUCCESS( Status ) ); // // Open the device. // InitializeObjectAttributes( &ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, (HANDLE) NULL, (PSECURITY_DESCRIPTOR) NULL ); Status = NtOpenFile( &FileHandle, FILE_WRITE_DATA | FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &ObjectAttributes, &IoStatus, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT ); RtlFreeUnicodeString( &UnicodeString ); if (!NT_SUCCESS( Status )) { DbgPrint( "format: error opening %s for input; error %X\n", DeviceName, Status ); return; } // // Issue the I/O control command // Status = NtDeviceIoControlFile( FileHandle, (HANDLE) NULL, (PIO_APC_ROUTINE) NULL, (PVOID) NULL, &IoStatus, IOCTL_DISK_DBG_GET_STATISTICS, NULL, 0L, &Buffer[0], (ULONG) sizeof( FLOPPY_STATISTICS ) ); if (!NT_SUCCESS( Status )) { DbgPrint( "getstatistics: error on NtDeviceIoControlFile; error %X\n", Status ); } else if (Status != STATUS_SUCCESS) { Status = NtWaitForSingleObject( FileHandle, TRUE, NULL ); if (Status == STATUS_SUCCESS) { if (!NT_SUCCESS( IoStatus.Status )) { if (IoStatus.Status == STATUS_NOT_IMPLEMENTED) { DbgPrint( "getstatistics: control function not implemented\n" ); } else { DbgPrint( "getstatistics: error %X\n", IoStatus.Status ); } } } } else { Statistics = (PFLOPPY_STATISTICS) &Buffer[0]; DbgPrint("\n"); DbgPrint( "Quick Fifo Reads: %d Slow Fifo Reads: %d\n", Statistics->QuickFifoReads, Statistics->SlowFifoReads ); DbgPrint( "Max Fifo Read Fast Tries: %d Max Fifo Write Fast Tries: %d\n", Statistics->MaxFifoReadFastTries, Statistics->MaxFifoWriteFastTries); DbgPrint( "Max Fifo Read Delay (ms): %d Fifo Read Failures: %d\n", Statistics->MaxFifoReadDelay, Statistics->FifoReadFailures ); DbgPrint( "Quick Fifo Writes: %d SlowFifoWrites: %d\n", Statistics->QuickFifoWrites, Statistics->SlowFifoWrites ); DbgPrint( "Max Fifo Write Delay (ms): %d Fifo Write Failures: %d\n", Statistics->MaxFifoWriteDelay, Statistics->FifoWriteFailures ); DbgPrint( "Controller Resets: %d\n", Statistics->ControllerResets ); DbgPrint( "ReadRequests: %d Write Requests: %d\n", Statistics->ReadRequests, Statistics->WriteRequests ); DbgPrint( "Format Requests: %d\n\n", Statistics->FormatRequests ); DbgPrint( "Reads frequency distribution:\n\n" ); Indicator = 'F'; for (i = 1; i <= MAX_FIFO_RW_TRIES; i++) { if (i > Statistics->MaxFastTries) { if (i <= Statistics->MaxStallTries + Statistics->MaxFastTries) { Indicator = 'S'; } else { Indicator = 'W'; } } if (Statistics->ReadsFrequency[i-1] > 0) { DbgPrint("R%c%d=%d; ", Indicator, i, Statistics->ReadsFrequency[i-1]); } } DbgPrint( " \n\n" ); DbgPrint( "Writes frequency distribution:\n\n" ); Indicator = 'F'; for (i = 0; i < MAX_FIFO_RW_TRIES; i++) { if (i > Statistics->MaxFastTries) { if (i <= Statistics->MaxStallTries + Statistics->MaxFastTries) { Indicator = 'S'; } else { Indicator = 'W'; } } if (Statistics->WritesFrequency[i-1] > 0) { DbgPrint("W%c%d=%d; ", Indicator, i, Statistics->WritesFrequency[i-1]); } } DbgPrint( " \n\n" ); DbgPrint( "Legenda for XYn=m : X={R(ead), W(rite)}, Y={F(ast), S(tall), W(ait)},\n"); DbgPrint( "n=retry #, m=frequency of success on retry #n.\n\n"); } // // Close the file. // (VOID) NtClose( FileHandle ); return; }
int main( int argc, char *argv[] ) { ULONG i; PSZ Psz; PPREFIX_TABLE_ENTRY PfxEntry; PPREFIX_NODE PfxNode; STRING String; // // We're starting the test // DbgPrint("Start Prefix Test\n"); // // Calculate the alphabet size for use by AnotherPrefix // AlphabetLength = strlen(Alphabet); // // Initialize the prefix table // PfxInitialize(&PrefixTable); // // Insert the root prefix // RtlInitString( &Prefixes[i].String, "\\" ); if (PfxInsertPrefix( &PrefixTable, &Prefixes[0].String, &Prefixes[0].PfxEntry )) { DbgPrint("Insert root prefix\n"); } else { DbgPrint("error inserting root prefix\n"); } // // Insert prefixes // Seed = 0; for (i = 1, Psz = AnotherPrefix(3); (i < PREFIXES) && (Psz != NULL); i += 1, Psz = AnotherPrefix(3)) { DbgPrint("[0x%x] = ", i); DbgPrint("\"%s\"", Psz); RtlInitString(&Prefixes[i].String, Psz); if (PfxInsertPrefix( &PrefixTable, &Prefixes[i].String, &Prefixes[i].PfxEntry )) { DbgPrint(" inserted in table\n"); } else { DbgPrint(" already in table\n"); } } // // Enumerate the prefix table // DbgPrint("Enumerate Prefix Table the first time\n"); for (PfxEntry = PfxNextPrefix(&PrefixTable, TRUE); PfxEntry != NULL; PfxEntry = PfxNextPrefix(&PrefixTable, FALSE)) { PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry); DbgPrint("%s\n", PfxNode->String.Buffer); } DbgPrint("Start Prefix search 0x%x\n", NextBufferChar); // // Search for prefixes // for (Psz = AnotherPrefix(4); Psz != NULL; Psz = AnotherPrefix(4)) { DbgPrint("0x%x ", NextBufferChar); RtlInitString(&String, Psz); PfxEntry = PfxFindPrefix( &PrefixTable, &String, FALSE ); if (PfxEntry == NULL) { PfxEntry = PfxFindPrefix( &PrefixTable, &String, TRUE ); if (PfxEntry == NULL) { DbgPrint("Not found \"%s\"\n", Psz); NOTHING; } else { PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry); DbgPrint("Case blind \"%s\" is \"%s\"\n", Psz, PfxNode->String.Buffer); PfxRemovePrefix( &PrefixTable, PfxEntry ); } } else { PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry); DbgPrint( "Case sensitive \"%s\" is \"%s\"\n", Psz, PfxNode->String.Buffer); if (PfxNode != &Prefixes[0]) { PfxRemovePrefix( &PrefixTable, PfxEntry ); } } } // // Enumerate the prefix table // DbgPrint("Enumerate Prefix Table a second time\n"); for (PfxEntry = PfxNextPrefix(&PrefixTable, TRUE); PfxEntry != NULL; PfxEntry = PfxNextPrefix(&PrefixTable, FALSE)) { PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry); DbgPrint("%s\n", PfxNode->String.Buffer); } // // Now enumerate and zero out the table // for (PfxEntry = PfxNextPrefix(&PrefixTable, TRUE); PfxEntry != NULL; PfxEntry = PfxNextPrefix(&PrefixTable, FALSE)) { PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry); DbgPrint("Delete %s\n", PfxNode->String.Buffer); PfxRemovePrefix( &PrefixTable, PfxEntry ); } // // Enumerate again but this time the table should be empty // for (PfxEntry = PfxNextPrefix(&PrefixTable, TRUE); PfxEntry != NULL; PfxEntry = PfxNextPrefix(&PrefixTable, FALSE)) { PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry); DbgPrint("This Node should be gone \"%s\"\n", PfxNode->String.Buffer); } DbgPrint("End PrefixTest()\n"); return TRUE; }
void impersonateToGetData(PCSTR user, PCSTR domain, PCSTR password, PCSTR kdc, PSID *sid, DWORD *rid, PCSTR usingWhat) { NTSTATUS status; DWORD ret, *aRid, *usage; ANSI_STRING aUser, aKdc, aDomain, aPass, aProg; UNICODE_STRING uUser, uKdc, uDomain, uPass, uProg; SAMPR_HANDLE hServerHandle, hDomainHandle; PSID domainSid; HANDLE hToken, hNewToken; PROCESS_INFORMATION processInfos; STARTUPINFOW startupInfo; RtlZeroMemory(&startupInfo, sizeof(STARTUPINFOW)); startupInfo.cb = sizeof(STARTUPINFOW); RtlInitString(&aUser, user); RtlInitString(&aKdc, kdc); RtlInitString(&aDomain, domain); RtlInitString(&aPass, password); RtlInitString(&aProg, usingWhat ? usingWhat : "winver.exe"); if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uUser, &aUser, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uKdc, &aKdc, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uDomain, &aDomain, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uPass, &aPass, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uProg, &aProg, TRUE))) { if(CreateProcessWithLogonW(uUser.Buffer, uDomain.Buffer, uPass.Buffer, LOGON_NETCREDENTIALS_ONLY, uProg.Buffer, NULL, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInfos)) { if(OpenProcessToken(processInfos.hProcess, TOKEN_DUPLICATE, &hToken)) { if(DuplicateTokenEx(hToken, TOKEN_QUERY | TOKEN_IMPERSONATE, NULL, SecurityDelegation, TokenImpersonation, &hNewToken)) { if(SetThreadToken(NULL, hNewToken)) { kprintf("[AUTH] Impersonation\n"); if(!(*sid && *rid)) { kprintf("[SID/RID] \'%s @ %s\' must be translated to SID/RID\n", user, domain); status = SamConnect(&uKdc, &hServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, FALSE); if(NT_SUCCESS(status)) { status = SamLookupDomainInSamServer(hServerHandle, &uDomain, &domainSid); if(NT_SUCCESS(status)) { status = SamOpenDomain(hServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, domainSid, &hDomainHandle); if(NT_SUCCESS(status)) { status = SamLookupNamesInDomain(hDomainHandle, 1, &uUser, &aRid, &usage); if(NT_SUCCESS(status)) *rid = *aRid; else PRINT_ERROR("SamLookupNamesInDomain %08x\n", status); } else PRINT_ERROR("SamOpenDomain %08x\n", status); ret = GetLengthSid(domainSid); if(*sid = (PSID) LocalAlloc(LPTR, ret)) { if(!CopySid(ret, *sid, domainSid)) { *sid = (PSID) LocalFree(*sid); PRINT_ERROR_AUTO("CopySid"); } } SamFreeMemory(domainSid); } else PRINT_ERROR("SamLookupDomainInSamServer %08x\n", status); SamCloseHandle(hServerHandle); } else PRINT_ERROR("SamConnect %08x\n", status); } RevertToSelf(); } else PRINT_ERROR_AUTO("SetThreadToken"); CloseHandle(hNewToken); } else PRINT_ERROR_AUTO("DuplicateTokenEx"); CloseHandle(hToken); } else PRINT_ERROR_AUTO("OpenProcessToken"); TerminateProcess(processInfos.hProcess, 0); CloseHandle(processInfos.hProcess); CloseHandle(processInfos.hThread); } else PRINT_ERROR_AUTO("CreateProcessWithLogonW"); RtlFreeUnicodeString(&uProg); } RtlFreeUnicodeString(&uPass); } RtlFreeUnicodeString(&uDomain); } RtlFreeUnicodeString(&uKdc); } RtlFreeUnicodeString(&uUser); } }
BOOLEAN obtest( void ) { ULONG i; HANDLE Handles[ 2 ]; NTSTATUS Status; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectTypeAName, "ObjectTypeA" ); RtlInitString( &ObjectTypeBName, "ObjectTypeB" ); RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) ); ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer ); ObjectTypeInitializer.ValidAccessMask = -1; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.MaintainHandleCount = TRUE; ObjectTypeInitializer.DumpProcedure = DumpAProc; ObjectTypeInitializer.OpenProcedure = OpenAProc; ObjectTypeInitializer.CloseProcedure = CloseAProc; ObjectTypeInitializer.DeleteProcedure = DeleteAProc; ObjectTypeInitializer.ParseProcedure = ParseAProc; ObCreateObjectType( &ObjectTypeAName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObjectTypeA ); ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.MaintainHandleCount = FALSE; ObjectTypeInitializer.GenericMapping = MyGenericMapping; ObjectTypeInitializer.DumpProcedure = DumpBProc; ObjectTypeInitializer.OpenProcedure = NULL; ObjectTypeInitializer.CloseProcedure = NULL; ObjectTypeInitializer.DeleteProcedure = DeleteBProc; ObjectTypeInitializer.ParseProcedure = NULL; ObCreateObjectType( &ObjectTypeBName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObjectTypeB ); ObpDumpTypes( NULL ); RtlInitString( &DirectoryName, "\\MyObjects" ); InitializeObjectAttributes( &DirectoryObjA, &DirectoryName, OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, NULL, NULL ); NtCreateDirectoryObject( &DirectoryHandle, 0, &DirectoryObjA ); NtClose( DirectoryHandle ); RtlInitString( &ObjectAName, "\\myobjects\\ObjectA" ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAName, OBJ_CASE_INSENSITIVE, NULL, NULL ); RtlInitString( &ObjectBName, "\\myobjects\\ObjectB" ); InitializeObjectAttributes( &ObjectBObjA, &ObjectBName, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = ObCreateObject( KernelMode, ObjectTypeA, &ObjectAObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEA ), 0L, 0L, (PVOID *)&ObjectBodyA ); ObjectA = (POBJECTTYPEA)ObjectBodyA; ObjectA->TypeALength = sizeof( *ObjectA ); for (i=0; i<4; i++) { ObjectA->Stuff[i] = i+1; } KeInitializeEvent( &ObjectA->Event, NotificationEvent, TRUE ); Status = ObCreateObject( KernelMode, ObjectTypeB, &ObjectBObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEB ), 0L, 0L, (PVOID *)&ObjectBodyB ); ObjectB = (POBJECTTYPEB)ObjectBodyB; ObjectB->TypeBLength = sizeof( *ObjectB ); for (i=0; i<16; i++) { ObjectB->Stuff[i] = i+1; } KeInitializeSemaphore ( &ObjectB->Semaphore, 2L, 2L ); Status = ObInsertObject( ObjectBodyA, SYNCHRONIZE | 0x3, NULL, 1, &ObjectBodyA, &ObjectHandleA1 ); DbgPrint( "Status: %lx ObjectBodyA: %lx ObjectHandleA1: %lx\n", Status, ObjectBodyA, ObjectHandleA1 ); Status = ObInsertObject( ObjectBodyB, SYNCHRONIZE | 0x1, NULL, 1, &ObjectBodyB, &ObjectHandleB1 ); DbgPrint( "Status: %lx ObjectBodyB: %lx ObjectHandleB1: %lx\n", Status, ObjectBodyB, ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectAName, "\\MyObjects\\ObjectA" ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAName, OBJ_OPENIF, NULL, NULL ); Status = ObCreateObject( KernelMode, ObjectTypeA, &ObjectAObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEA ), 0L, 0L, (PVOID *)&ObjectBodyA1 ); Status = ObInsertObject( ObjectBodyA1, SYNCHRONIZE | 0x3, NULL, 1, &ObjectBodyA2, &ObjectHandleA2 ); DbgPrint( "Status: %lx ObjectBodyA1: %lx ObjectBodyA2: %lx ObjectHandleA2: %lx\n", Status, ObjectBodyA1, ObjectBodyA2, ObjectHandleA2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); NtClose( ObjectHandleA2 ); ObDereferenceObject( ObjectBodyA2 ); // ObInsertObject,ObjectPointerBias NtWaitForSingleObject( ObjectHandleB1, TRUE, NULL ); Handles[ 0 ] = ObjectHandleA1; Handles[ 1 ] = ObjectHandleB1; NtWaitForMultipleObjects( 2, Handles, WaitAny, TRUE, NULL ); ObReferenceObjectByHandle( ObjectHandleA1, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB1, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByPointer( ObjectBodyA, 0L, ObjectTypeA, KernelMode ); ObReferenceObjectByPointer( ObjectBodyB, 0L, ObjectTypeB, KernelMode ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectAPathName, "\\MyObjects\\ObjectA" ); RtlInitString( &ObjectBPathName, "\\MyObjects\\ObjectB" ); ObReferenceObjectByName( &ObjectAPathName, OBJ_CASE_INSENSITIVE, 0L, ObjectTypeA, KernelMode, NULL, &ObjectBodyA ); ObReferenceObjectByName( &ObjectBPathName, OBJ_CASE_INSENSITIVE, 0L, ObjectTypeB, KernelMode, NULL, &ObjectBodyB ); DbgPrint( "Reference Name %s = %lx\n", ObjectAPathName.Buffer, ObjectBodyA ); DbgPrint( "Reference Name %s = %lx\n", ObjectBPathName.Buffer, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObDereferenceObject( ObjectBodyA ); // ObInsertObject,ObjectPointerBias ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByPointer ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByName ObDereferenceObject( ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAPathName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObOpenObjectByName( &ObjectAObjA, 0L, NULL, ObjectTypeA, KernelMode, NULL, &ObjectHandleA2 ); InitializeObjectAttributes( &ObjectBObjA, &ObjectBPathName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObOpenObjectByName( &ObjectBObjA, 0L, NULL, ObjectTypeB, KernelMode, NULL, &ObjectHandleB2 ); DbgPrint( "Open Object Name %s = %lx\n", ObjectAPathName.Buffer, ObjectHandleA2 ); DbgPrint( "Open Object Name %s = %lx\n", ObjectBPathName.Buffer, ObjectHandleB2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); NtClose( ObjectHandleA1 ); NtClose( ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByHandle( ObjectHandleA2, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB2, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA2, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB2, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObOpenObjectByPointer( ObjectBodyA, OBJ_CASE_INSENSITIVE, 0L, NULL, ObjectTypeA, KernelMode, &ObjectHandleA1 ); ObOpenObjectByPointer( ObjectBodyB, OBJ_CASE_INSENSITIVE, 0L, NULL, ObjectTypeB, KernelMode, &ObjectHandleB1 ); DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyA, ObjectHandleA1 ); DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyB, ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByHandle( ObjectHandleA1, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB1, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); NtClose( ObjectHandleA1 ); NtClose( ObjectHandleB1 ); NtClose( ObjectHandleA2 ); NtClose( ObjectHandleB2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); TestFunction = NULL; return( TRUE ); }
VOID Read( IN PCHAR FileName, IN ULONG FileTime, IN ULONG FileCount ) { NTSTATUS Status; HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; IO_STATUS_BLOCK IoStatus; LARGE_INTEGER AllocationSize; LARGE_INTEGER ByteOffset; ULONG Count; ULONG Pattern[3]; // // Get the filename // simprintf("Read ", 0); simprintf(FileName, 0); simprintf("\n", 0); // // Open the existing file // AllocationSize = LiFromUlong( FileCount * 4 ); RtlInitString( &NameString, FileName ); InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL ); if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle, FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &ObjectAttributes, &IoStatus, 0L, WriteThrough ))) { OpenFileError( Status, FileName ); return; } // // The main loop read in the test pattern our test pattern // is <FileTime> <FileSize> <Count> where count is the current // iteration count for the current test pattern output. // for (Count = 0; Count < FileCount; Count += 1) { ByteOffset = LiFromUlong( Count * 3 * 4 ); if (!NT_SUCCESS(Status = NtReadFile( FileHandle, (HANDLE)NULL, (PIO_APC_ROUTINE)NULL, (PVOID)NULL, &IoStatus, Pattern, 3 * 4, &ByteOffset, (PULONG) NULL ))) { ReadFileError( Status ); return; } if (!NT_SUCCESS(Status = NtWaitForSingleObject(FileHandle, TRUE, NULL))) { WaitForSingleObjectError( Status ); return; } // // check how the read turned out // CheckIoStatus( &IoStatus, 3 * 4, TRUE ); if (!NT_SUCCESS(IoStatus.Status)) { IoStatusError( IoStatus.Status ); break; } // // Now compare the what we read with what we should have read // if ((Pattern[0] != FileTime) || (Pattern[1] != FileCount) || (Pattern[2] != Count)) { printf("**** Read Error ****\n"); NtPartyByNumber( 50 ); return; } } // // Now close the file // if (!NT_SUCCESS(Status = NtClose( FileHandle ))) { CloseError( Status ); } // // And return to our caller // return; }
VOID Delete( IN PCHAR FileName ) { NTSTATUS Status; HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; IO_STATUS_BLOCK IoStatus; // // Get the filename // simprintf("Delete ", 0); simprintf(FileName, 0); simprintf("\n", 0); // // Open the file for delete access // RtlInitString( &NameString, FileName ); InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL ); if (!NT_SUCCESS(Status = NtCreateFile( &FileHandle, DELETE | SYNCHRONIZE, &ObjectAttributes, &IoStatus, (PLARGE_INTEGER)NULL, 0L, 0L, FILE_OPEN, WriteThrough, (PVOID)NULL, 0L ))) { CreateFileError( Status, FileName ); return; } // // Mark the file for delete // ((PFILE_DISPOSITION_INFORMATION)&Buffer[0])->DeleteFile = TRUE; if (!NT_SUCCESS(Status = NtSetInformationFile( FileHandle, &IoStatus, Buffer, sizeof(FILE_DISPOSITION_INFORMATION), FileDispositionInformation))) { SetInformationFileError( Status ); return; } // // Now close the file // if (!NT_SUCCESS(Status = NtClose( FileHandle ))) { CloseError( Status ); } // // And return to our caller // return; }
VOID GetMediaTypes ( OUT PDISK_GEOMETRY OutputBuffer ) { HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; UNICODE_STRING UnicodeString; IO_STATUS_BLOCK IoStatus; NTSTATUS Status; PCHAR DeviceName; PDISK_GEOMETRY MediaTypes; DeviceName = &DriveA[0]; RtlInitString( &NameString, DeviceName ); Status = RtlAnsiStringToUnicodeString( &UnicodeString, &NameString, TRUE ); ASSERT( NT_SUCCESS( Status ) ); // // Open the device. // InitializeObjectAttributes( &ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, (HANDLE) NULL, (PSECURITY_DESCRIPTOR) NULL ); Status = NtOpenFile( &FileHandle, FILE_WRITE_DATA | FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &ObjectAttributes, &IoStatus, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT ); RtlFreeUnicodeString( &UnicodeString ); if (!NT_SUCCESS( Status )) { DbgPrint( "GetMediaTypes: error opening %s for input; error %X\n", DeviceName, Status ); return; } // // Issue the I/O control command // Status = NtDeviceIoControlFile( FileHandle, (HANDLE) NULL, (PIO_APC_ROUTINE) NULL, (PVOID) NULL, &IoStatus, IOCTL_DISK_GET_MEDIA_TYPES, NULL, 0L, &Buffer[0], (ULONG) sizeof( DISK_GEOMETRY ) * MAX_NUMBER_OF_MEDIA_TYPES ); if (!NT_SUCCESS( Status )) { DbgPrint( "GetMediaTypes: error on NtDeviceIoControlFile; error %X\n", Status ); } else if (Status != STATUS_SUCCESS) { Status = NtWaitForSingleObject( FileHandle, TRUE, NULL ); if (Status == STATUS_SUCCESS) { if (!NT_SUCCESS( IoStatus.Status )) { if (IoStatus.Status == STATUS_NOT_IMPLEMENTED) { DbgPrint( "GetMediaTypes: control function not implemented\n" ); } else { DbgPrint( "GetMediaTypes: error %X\n", IoStatus.Status ); } } } } else { MediaTypes = (PDISK_GEOMETRY) &Buffer[0]; DbgPrint( "Media Type Sector Size Sectors/Track Cylinders Heads\n" ); while (IoStatus.Information >= sizeof( DISK_GEOMETRY )) { DbgPrint( " %d %d %d %d %d\n", MediaTypes->MediaType, MediaTypes->SectorSize, MediaTypes->SectorsPerTrack, MediaTypes->Cylinders, MediaTypes->Heads); if (OutputBuffer != NULL) { *OutputBuffer++ = *MediaTypes; } IoStatus.Information -= sizeof( DISK_GEOMETRY ); MediaTypes++; } } // // Close the file. // (VOID) NtClose( FileHandle ); return; }
VOID DoTest( HANDLE RootKey ) { NTSTATUS rc; STRING String1; UCHAR Value1[] = "This string is value 1."; UCHAR Value2[] = "Value 2 is represented by this string."; HANDLE Handle1; HANDLE Handle2; ULONG ValueLength; ULONG Type; LARGE_INTEGER Time; // // Create parent node // DbgPrint("Part1\n"); RtlInitString(&String1, "Test1"); rc = NtCreateKey( RootKey, &String1, 0, NULL, GENERIC_READ|GENERIC_WRITE, &Handle1 ); if (!NT_SUCCESS(rc)) { DbgPrint("1:CreateKey failed rc = %08lx", rc); return; } // // Set data into parent // DbgPrint("Part2\n"); rc = NtSetValueKey( Handle1, 1, // type Value1, strlen(Value1) ); if (!NT_SUCCESS(rc)) { DbgPrint("2:SetValueKey failed rc = %08lx", rc); return; } // // Query and compare data from parent // DbgPrint("Part2b\n"); ValueLength = MAX_VALUE; rc = NtQueryValueKey( Handle1, &Type, ValueBuffer, &ValueLength, &Time ); if (!NT_SUCCESS(rc)) { DbgPrint("2b:QueryValueKey failed rc = %08lx", rc); return; } if (ValueLength != (ULONG)strlen(Value1)) { DbgPrint("2b1:Wrong value length\n"); return; } else if (RtlCompareMemory( ValueBuffer, Value1, ValueLength) != ValueLength) { DbgPrint("2b2:Wrong value\n"); return; } else if (Type != 1) { DbgPrint("2b3:Wrong type\n"); return; } // // Close parent // DbgPrint("Part3\n"); NtCloseKey(Handle1); if (!NT_SUCCESS(rc)) { DbgPrint("3:CloseKey failed rc = %08lx", rc); return; } // // Reopen parent // DbgPrint("Part4\n"); rc = NtOpenKey( RootKey, &String1, 0, GENERIC_READ|GENERIC_WRITE, &Handle1 ); if (!NT_SUCCESS(rc)) { DbgPrint("4:OpenKey failed rc = %08lx", rc); return; } // // Create child // DbgPrint("Part5\n"); RtlInitString(&String1, "Test2"); rc = NtCreateKey( Handle1, &String1, 0, NULL, GENERIC_READ|GENERIC_WRITE, &Handle2 ); if (!NT_SUCCESS(rc)) { DbgPrint("5:CreateKey failed rc = %08lx", rc); return; } // // Set data into child // DbgPrint("Part6\n"); rc = NtSetValueKey( Handle2, 2, // type Value2, strlen(Value2) ); if (!NT_SUCCESS(rc)) { DbgPrint("6:SetValueKey failed rc = %08lx", rc); return; } // // Query and compare data from child // DbgPrint("Part7\n"); ValueLength = MAX_VALUE; rc = NtQueryValueKey( Handle2, &Type, ValueBuffer, &ValueLength, &Time ); if (!NT_SUCCESS(rc)) { DbgPrint("7:QueryValueKey failed rc = %08lx", rc); return; } if (ValueLength != (ULONG)strlen(Value2)) { DbgPrint("7.1:Wrong value length\n"); return; } else if (RtlCompareMemory( ValueBuffer, Value2, ValueLength) != ValueLength) { DbgPrint("7.2:Wrong value\n"); return; } else if (Type != 2) { DbgPrint("7.3:Wrong type\n"); return; } // // Query and compare data from parent again // DbgPrint("Part8\n"); ValueLength = MAX_VALUE; rc = NtQueryValueKey( Handle1, &Type, ValueBuffer, &ValueLength, &Time ); if (!NT_SUCCESS(rc)) { DbgPrint("8:QueryValueKey failed rc = %08lx", rc); return; } if (ValueLength != (ULONG)strlen(Value1)) { DbgPrint("8.1:Wrong value length\n"); return; } else if (RtlCompareMemory( ValueBuffer, Value1, ValueLength) != ValueLength) { DbgPrint("8.2:Wrong value\n"); return; } else if (Type != 1) { DbgPrint("8.3:Wrong type\n"); return; } // // Reset parent data // DbgPrint("Part9\n"); rc = NtSetValueKey( Handle1, 1, // type Value2, strlen(Value2) ); if (!NT_SUCCESS(rc)) { DbgPrint("9:SetValueKey failed rc = %08lx", rc); return; } // // Query and compare reset data // DbgPrint("Part10\n"); ValueLength = MAX_VALUE; rc = NtQueryValueKey( Handle1, &Type, ValueBuffer, &ValueLength, &Time ); if (!NT_SUCCESS(rc)) { DbgPrint("10:QueryValueKey failed rc = %08lx", rc); return; } if (ValueLength != (ULONG)strlen(Value2)) { DbgPrint("10.1:Wrong value length\n"); return; } else if (RtlCompareMemory( ValueBuffer, Value2, ValueLength) != ValueLength) { DbgPrint("10.2:Wrong value\n"); return; } else if (Type != 1) { DbgPrint("10.3:Wrong type\n"); return; } // // Close off handles and return // DbgPrint("Part11\n"); rc = NtCloseKey(Handle1); if (!NT_SUCCESS(rc)) { DbgPrint("11:CloseKey failed rc = %08lx", rc); return; } DbgPrint("Part12\n"); rc = NtCloseKey(Handle2); if (!NT_SUCCESS(rc)) { DbgPrint("12:CloseKey failed rc = %08lx", rc); return; } return; }
VOID FormatSomeTracks ( CHAR DeviceId ) { HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; UNICODE_STRING UnicodeString; IO_STATUS_BLOCK IoStatus; NTSTATUS Status; PCHAR DeviceName; FORMAT_PARAMETERS FormatParameters; BAD_TRACK_NUMBER BadTracks[80]; ULONG i; if (DeviceId == '1') { DeviceName = &DriveA[0]; } else if (DeviceId == '2') { DeviceName = &DriveB[0]; } else { DbgPrint( "Format: invalid drive id '%c'\n", DeviceId ); return; } GetMediaTypes( NULL ); Zero( &Buffer[0], 10 ); DbgPrompt( "Enter media type code: ", Buffer, 10 ); FormatParameters.MediaType = (MEDIA_TYPE) atoi( &Buffer[0] ); Zero( &Buffer[0], 10 ); DbgPrompt( "Enter start cylinder: ", Buffer, 10 ); FormatParameters.StartCylinderNumber = (ULONG) atoi( &Buffer[0] ); Zero( &Buffer[0], 10 ); DbgPrompt( "Enter end cylinder: ", Buffer, 10 ); FormatParameters.EndCylinderNumber = (ULONG) atoi( &Buffer[0] ); Zero( &Buffer[0], 10 ); DbgPrompt( "Enter start head: ", Buffer, 10 ); FormatParameters.StartHeadNumber = (ULONG) atoi( &Buffer[0] ); Zero( &Buffer[0], 10 ); DbgPrompt( "Enter end head: ", Buffer, 10 ); FormatParameters.EndHeadNumber = (ULONG) atoi( &Buffer[0] ); RtlInitString( &NameString, DeviceName ); Status = RtlAnsiStringToUnicodeString( &UnicodeString, &NameString, TRUE ); ASSERT( NT_SUCCESS( Status ) ); // // Open the device. // InitializeObjectAttributes( &ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, (HANDLE) NULL, (PSECURITY_DESCRIPTOR) NULL ); Status = NtOpenFile( &FileHandle, FILE_WRITE_DATA | FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &ObjectAttributes, &IoStatus, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT ); RtlFreeUnicodeString( &UnicodeString ); if (!NT_SUCCESS( Status )) { DbgPrint( "format: error opening %s for input; error %X\n", DeviceName, Status ); return; } DbgPrompt( "\nInsert diskette and press RETURN when ready ", Buffer, 256 ); // // Issue the format command. // Status = NtDeviceIoControlFile( FileHandle, (HANDLE) NULL, (PIO_APC_ROUTINE) NULL, (PVOID) NULL, &IoStatus, IOCTL_DISK_FORMAT_TRACKS, &FormatParameters, (ULONG) sizeof( FormatParameters ), &BadTracks[0], (ULONG) sizeof( BadTracks ) ); if (!NT_SUCCESS( Status )) { DbgPrint( "format: error on NtDeviceIoControlFile; error %X\n", Status ); } else if (Status != STATUS_SUCCESS) { Status = NtWaitForSingleObject( FileHandle, TRUE, NULL ); if (Status == STATUS_SUCCESS) { if (!NT_SUCCESS( IoStatus.Status )) { if (IoStatus.Status == STATUS_NOT_IMPLEMENTED) { DbgPrint( "format: control function not implemented\n" ); } if (IoStatus.Status == STATUS_MEDIA_WRITE_PROTECTED) { DbgPrint( "format: media is write protected\n" ); } else if (IoStatus.Status == STATUS_DEVICE_NOT_READY) { DbgPrint( "format: device not ready\n" ); } else { DbgPrint( "format: error %X\n", IoStatus.Status ); } } } } else { if (IoStatus.Information) { // // Found some bad tracks. // i = 0; DbgPrint( "Bad tracks: " ); while (IoStatus.Information >= sizeof( BAD_TRACK_NUMBER )) { DbgPrint( "%d ", BadTracks[i++] ); IoStatus.Information -= sizeof( BAD_TRACK_NUMBER ); } DbgPrint( " \n" ); } } // // Close the file. // (VOID) NtClose( FileHandle ); return; }