NTSTATUS SetAdministratorPassword(LPCWSTR Password) { PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL; PUSER_ACCOUNT_NAME_INFORMATION AccountNameInfo = NULL; USER_SET_PASSWORD_INFORMATION PasswordInfo; LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE PolicyHandle = NULL; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE DomainHandle = NULL; SAM_HANDLE UserHandle = NULL; NTSTATUS Status; DPRINT("SYSSETUP: SetAdministratorPassword(%p)\n", Password); memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES); Status = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN, &PolicyHandle); if (Status != STATUS_SUCCESS) { DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status); return Status; } Status = LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (PVOID *)&OrigInfo); if (!NT_SUCCESS(Status)) { DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status); goto done; } Status = SamConnect(NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status); goto done; } Status = SamOpenDomain(ServerHandle, DOMAIN_LOOKUP, OrigInfo->DomainSid, &DomainHandle); if (!NT_SUCCESS(Status)) { DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status); goto done; } Status = SamOpenUser(DomainHandle, USER_FORCE_PASSWORD_CHANGE | USER_READ_GENERAL, DOMAIN_USER_RID_ADMIN, &UserHandle); if (!NT_SUCCESS(Status)) { DPRINT1("SamOpenUser() failed (Status %08lx)\n", Status); goto done; } RtlInitUnicodeString(&PasswordInfo.Password, Password); PasswordInfo.PasswordExpired = FALSE; Status = SamSetInformationUser(UserHandle, UserSetPasswordInformation, (PVOID)&PasswordInfo); if (!NT_SUCCESS(Status)) { DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status); goto done; } Status = SamQueryInformationUser(UserHandle, UserAccountNameInformation, (PVOID*)&AccountNameInfo); if (!NT_SUCCESS(Status)) { DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status); goto done; } AdminInfo.Name = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, AccountNameInfo->UserName.Length + sizeof(WCHAR)); if (AdminInfo.Name != NULL) RtlCopyMemory(AdminInfo.Name, AccountNameInfo->UserName.Buffer, AccountNameInfo->UserName.Length); AdminInfo.Domain = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, OrigInfo->DomainName.Length + sizeof(WCHAR)); if (AdminInfo.Domain != NULL) RtlCopyMemory(AdminInfo.Domain, OrigInfo->DomainName.Buffer, OrigInfo->DomainName.Length); AdminInfo.Password = RtlAllocateHeap(RtlGetProcessHeap(), 0, (wcslen(Password) + 1) * sizeof(WCHAR)); if (AdminInfo.Password != NULL) wcscpy(AdminInfo.Password, Password); DPRINT("Administrator Name: %S\n", AdminInfo.Name); DPRINT("Administrator Domain: %S\n", AdminInfo.Domain); DPRINT("Administrator Password: %S\n", AdminInfo.Password); done: if (AccountNameInfo != NULL) SamFreeMemory(AccountNameInfo); if (OrigInfo != NULL) LsaFreeMemory(OrigInfo); if (PolicyHandle != NULL) LsaClose(PolicyHandle); if (UserHandle != NULL) SamCloseHandle(UserHandle); if (DomainHandle != NULL) SamCloseHandle(DomainHandle); if (ServerHandle != NULL) SamCloseHandle(ServerHandle); DPRINT1("SYSSETUP: SetAdministratorPassword() done (Status %08lx)\n", Status); return Status; }
/* * @implemented */ BOOL WINAPI MoveFileWithProgressW ( LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, LPPROGRESS_ROUTINE lpProgressRoutine, LPVOID lpData, DWORD dwFlags ) { HANDLE hFile = NULL, hNewFile = NULL; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; PFILE_RENAME_INFORMATION FileRename; NTSTATUS errCode; BOOL Result; UNICODE_STRING DstPathU; BOOL folder = FALSE; TRACE("MoveFileWithProgressW()\n"); if (dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT) return add_boot_rename_entry( lpExistingFileName, lpNewFileName, dwFlags ); // if (dwFlags & MOVEFILE_WRITE_THROUGH) // FIXME("MOVEFILE_WRITE_THROUGH unimplemented\n"); if (!lpNewFileName) return DeleteFileW(lpExistingFileName); /* validate & translate the filename */ if (!RtlDosPathNameToNtPathName_U (lpNewFileName, &DstPathU, NULL, NULL)) { WARN("Invalid destination path\n"); SetLastError(ERROR_PATH_NOT_FOUND); return FALSE; } InitializeObjectAttributes(&ObjectAttributes, &DstPathU, OBJ_CASE_INSENSITIVE, NULL, NULL); errCode = NtOpenFile( &hNewFile, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | ((dwFlags & MOVEFILE_WRITE_THROUGH) ? FILE_WRITE_THROUGH : 0) ); if (NT_SUCCESS(errCode)) /* Destination exists */ { NtClose(hNewFile); if (!(dwFlags & MOVEFILE_REPLACE_EXISTING)) { SetLastError(ERROR_ALREADY_EXISTS); return FALSE; } else if (GetFileAttributesW(lpNewFileName) & FILE_ATTRIBUTE_DIRECTORY) { SetLastError(ERROR_ACCESS_DENIED); return FALSE; } } hFile = CreateFileW (lpExistingFileName, GENERIC_ALL, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | ((dwFlags & MOVEFILE_WRITE_THROUGH) ? FILE_FLAG_WRITE_THROUGH : 0), NULL); if (hFile == INVALID_HANDLE_VALUE) { return FALSE; } FileRename = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length); if( !FileRename ) { CloseHandle(hFile); SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } if( dwFlags & MOVEFILE_REPLACE_EXISTING ) { FileRename->ReplaceIfExists = TRUE; } else { FileRename->ReplaceIfExists = FALSE; } memcpy(FileRename->FileName, DstPathU.Buffer, DstPathU.Length); RtlFreeHeap (RtlGetProcessHeap (), 0, DstPathU.Buffer); FileRename->FileNameLength = DstPathU.Length; errCode = NtSetInformationFile (hFile, &IoStatusBlock, FileRename, sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length, FileRenameInformation); CloseHandle(hFile); RtlFreeHeap(RtlGetProcessHeap(), 0, FileRename); if (GetFileAttributesW(lpExistingFileName) & FILE_ATTRIBUTE_DIRECTORY) { folder = TRUE; } /* * FIXME: * Fail now move the folder * Before we fail at CreateFileW */ if (NT_SUCCESS(errCode)) { Result = TRUE; } else { if (folder==FALSE) { Result = CopyFileExW (lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, NULL, (dwFlags & MOVEFILE_REPLACE_EXISTING) ? 0 : COPY_FILE_FAIL_IF_EXISTS); if (Result) { /* Cleanup the source file */ Result = DeleteFileW (lpExistingFileName); } } else { /* move folder code start */ WIN32_FIND_DATAW findBuffer; LPWSTR lpExistingFileName2 = NULL; LPWSTR lpNewFileName2 = NULL; LPWSTR lpDeleteFile = NULL; INT size; INT size2; BOOL loop = TRUE; BOOL Result = FALSE; INT max_size = MAX_PATH; /* Build the string */ size = wcslen(lpExistingFileName); if (size+6> max_size) max_size = size + 6; lpDeleteFile = (LPWSTR) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,max_size * sizeof(WCHAR)); if (lpDeleteFile == NULL) return FALSE; lpNewFileName2 = (LPWSTR) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,max_size * sizeof(WCHAR)); if (lpNewFileName2 == NULL) { HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile); return FALSE; } lpExistingFileName2 = (LPWSTR) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,max_size * sizeof(WCHAR)); if (lpExistingFileName2 == NULL) { HeapFree(GetProcessHeap(),0,(VOID *) lpNewFileName2); HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile); return FALSE; } wcscpy( (WCHAR *)lpExistingFileName2,lpExistingFileName); wcscpy( (WCHAR *)&lpExistingFileName2[size],L"\\*.*\0"); /* Get the file name */ memset(&findBuffer,0,sizeof(WIN32_FIND_DATAW)); hFile = FindFirstFileW(lpExistingFileName2, &findBuffer); if (hFile == INVALID_HANDLE_VALUE) loop=FALSE; if (findBuffer.cFileName[0] == L'\0') loop=FALSE; /* FIXME * remove readonly flag from source folder and do not set the readonly flag to dest folder */ RemoveReadOnlyAttributeW(lpExistingFileName); RemoveReadOnlyAttributeW(lpNewFileName); //CreateDirectoryExW(lpExistingFileName,lpNewFileName,NULL); CreateDirectoryW(lpNewFileName, NULL); /* search the files/folders and move them */ while (loop==TRUE) { Result = TRUE; if ((!wcscmp(findBuffer.cFileName,L"..")) || (!wcscmp(findBuffer.cFileName,L"."))) { loop = FindNextFileW(hFile, &findBuffer); if (!loop) { size = wcslen(lpExistingFileName2)-4; FindClose(hFile); hFile = INVALID_HANDLE_VALUE; wcscpy( &lpExistingFileName2[size],L"\0"); if (wcsncmp(lpExistingFileName,lpExistingFileName2,size)) { DWORD Attributes; /* delete folder */ TRACE("MoveFileWithProgressW : Delete folder : %S\n",lpDeleteFile); /* remove system folder flag other wise we can not delete the folder */ Attributes = GetFileAttributesW(lpExistingFileName2); if (Attributes != INVALID_FILE_ATTRIBUTES) { SetFileAttributesW(lpExistingFileName2,(Attributes & ~FILE_ATTRIBUTE_SYSTEM)); } RemoveReadOnlyAttributeW(lpExistingFileName2); Result = RemoveDirectoryW(lpExistingFileName2); if (Result == FALSE) break; loop=TRUE; size = wcslen(lpExistingFileName); if (size+6>max_size) { if (lpNewFileName2 != NULL) HeapFree(GetProcessHeap(),0,(VOID *) lpNewFileName2); if (lpExistingFileName2 != NULL) HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2); if (lpDeleteFile != NULL) HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile); return FALSE; } wcscpy( lpExistingFileName2,lpExistingFileName); wcscpy( &lpExistingFileName2[size],L"\\*.*\0"); /* Get the file name */ memset(&findBuffer,0,sizeof(WIN32_FIND_DATAW)); hFile = FindFirstFileW(lpExistingFileName2, &findBuffer); } } continue; } if (findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { /* Build the new src string */ size = wcslen(findBuffer.cFileName); size2= wcslen(lpExistingFileName2); if (size2+size+6>max_size) { FindClose(hFile); if (lpNewFileName2 != NULL) HeapFree(GetProcessHeap(),0,(VOID *) lpNewFileName2); if (lpExistingFileName2 != NULL) HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2); if (lpDeleteFile != NULL) HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile); return FALSE; } wcscpy( &lpExistingFileName2[size2-3],findBuffer.cFileName); wcscpy( &lpExistingFileName2[size2+size-3],L"\0"); /* Continue */ wcscpy( lpDeleteFile,lpExistingFileName2); wcscpy( &lpExistingFileName2[size2+size-3],L"\\*.*\0"); /* Build the new dst string */ size = wcslen(lpExistingFileName2) + wcslen(lpNewFileName); size2 = wcslen(lpExistingFileName); if (size>max_size) { FindClose(hFile); if (lpNewFileName2 != NULL) HeapFree(GetProcessHeap(),0,(VOID *) lpNewFileName2); if (lpExistingFileName2 != NULL) HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2); if (lpDeleteFile != NULL) HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile); return FALSE; } wcscpy( lpNewFileName2,lpNewFileName); size = wcslen(lpNewFileName); wcscpy( &lpNewFileName2[size], &lpExistingFileName2[size2]); size = wcslen(lpNewFileName2); wcscpy( &lpNewFileName2[size-4],L"\0"); /* Create Folder */ /* FIXME * remove readonly flag from source folder and do not set the readonly flag to dest folder */ RemoveReadOnlyAttributeW(lpDeleteFile); RemoveReadOnlyAttributeW(lpNewFileName2); CreateDirectoryW(lpNewFileName2,NULL); //CreateDirectoryExW(lpDeleteFile, lpNewFileName2,NULL); /* set new search path from src string */ FindClose(hFile); memset(&findBuffer,0,sizeof(WIN32_FIND_DATAW)); hFile = FindFirstFileW(lpExistingFileName2, &findBuffer); } else { /* Build the new string */ size = wcslen(findBuffer.cFileName); size2= wcslen(lpExistingFileName2); wcscpy( lpDeleteFile,lpExistingFileName2); wcscpy( &lpDeleteFile[size2-3],findBuffer.cFileName); /* Build dest string */ size = wcslen(lpDeleteFile) + wcslen(lpNewFileName); size2 = wcslen(lpExistingFileName); if (size>max_size) { FindClose(hFile); if (lpNewFileName2 != NULL) HeapFree(GetProcessHeap(),0,(VOID *) lpNewFileName2); if (lpExistingFileName2 != NULL) HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2); if (lpDeleteFile != NULL) HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile); return FALSE; } wcscpy( lpNewFileName2,lpNewFileName); size = wcslen(lpNewFileName); wcscpy(&lpNewFileName2[size],&lpDeleteFile[size2]); /* overrite existsen file, if the file got the flag have readonly * we need reomve that flag */ /* copy file */ TRACE("MoveFileWithProgressW : Copy file : %S to %S\n",lpDeleteFile, lpNewFileName2); RemoveReadOnlyAttributeW(lpDeleteFile); RemoveReadOnlyAttributeW(lpNewFileName2); Result = CopyFileExW (lpDeleteFile, lpNewFileName2, lpProgressRoutine, lpData, NULL, 0); if (Result == FALSE) break; /* delete file */ TRACE("MoveFileWithProgressW : remove readonly flag from file : %S\n",lpNewFileName2); Result = RemoveReadOnlyAttributeW(lpDeleteFile); if (Result == FALSE) break; TRACE("MoveFileWithProgressW : Delete file : %S\n",lpDeleteFile); Result = DeleteFileW(lpDeleteFile); if (Result == FALSE) break; } loop = FindNextFileW(hFile, &findBuffer); } /* Remove last folder */ if ((loop == FALSE) && (Result != FALSE)) { DWORD Attributes; Attributes = GetFileAttributesW(lpDeleteFile); if (Attributes != INVALID_FILE_ATTRIBUTES) { SetFileAttributesW(lpDeleteFile,(Attributes & ~FILE_ATTRIBUTE_SYSTEM)); } Result = RemoveDirectoryW(lpExistingFileName); } /* Cleanup */ FindClose(hFile); if (lpNewFileName2 != NULL) { HeapFree(GetProcessHeap(),0,(VOID *) lpNewFileName2); lpNewFileName2 = NULL; } if (lpExistingFileName2 != NULL) { HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2); lpExistingFileName2 = NULL; } if (lpDeleteFile != NULL) { HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile); lpDeleteFile = NULL; } return Result; // end move folder code } } return Result; }
NTSTATUS SampRegEnumerateValue(IN HANDLE KeyHandle, IN ULONG Index, OUT LPWSTR Name, IN OUT PULONG NameLength, OUT PULONG Type OPTIONAL, OUT PVOID Data OPTIONAL, IN OUT PULONG DataLength OPTIONAL) { PKEY_VALUE_FULL_INFORMATION ValueInfo = NULL; ULONG BufferLength = 0; ULONG ReturnedLength; NTSTATUS Status; TRACE("Index: %lu\n", Index); /* Calculate the required buffer length */ BufferLength = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name); BufferLength += (MAX_PATH + 1) * sizeof(WCHAR); if (Data != NULL) BufferLength += *DataLength; /* Allocate the value buffer */ ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); if (ValueInfo == NULL) return STATUS_NO_MEMORY; /* Enumerate the value*/ Status = ZwEnumerateValueKey(KeyHandle, Index, KeyValueFullInformation, ValueInfo, BufferLength, &ReturnedLength); if (NT_SUCCESS(Status)) { if (Name != NULL) { /* Check if the name fits */ if (ValueInfo->NameLength < (*NameLength * sizeof(WCHAR))) { /* Copy it */ RtlMoveMemory(Name, ValueInfo->Name, ValueInfo->NameLength); /* Terminate the string */ Name[ValueInfo->NameLength / sizeof(WCHAR)] = 0; } else { /* Otherwise, we ran out of buffer space */ Status = STATUS_BUFFER_OVERFLOW; goto done; } } if (Data != NULL) { /* Check if the data fits */ if (ValueInfo->DataLength <= *DataLength) { /* Copy it */ RtlMoveMemory(Data, (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset), ValueInfo->DataLength); /* if the type is REG_SZ and data is not 0-terminated * and there is enough space in the buffer NT appends a \0 */ if (IsStringType(ValueInfo->Type) && ValueInfo->DataLength <= *DataLength - sizeof(WCHAR)) { WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength); if ((ptr > (WCHAR *)Data) && ptr[-1]) *ptr = 0; } } else { Status = STATUS_BUFFER_OVERFLOW; goto done; } } } done: if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) { if (Type != NULL) *Type = ValueInfo->Type; if (NameLength != NULL) *NameLength = ValueInfo->NameLength; if (DataLength != NULL) *DataLength = ValueInfo->DataLength; } /* Free the buffer and return status */ if (ValueInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo); return Status; }
static VOID ScanForUnpartitionedDiskSpace( PDISKENTRY DiskEntry) { ULONGLONG LastStartSector; ULONGLONG LastSectorCount; ULONGLONG LastUnusedSectorCount; PPARTENTRY PartEntry; PPARTENTRY NewPartEntry; PLIST_ENTRY Entry; DPRINT("ScanForUnpartitionedDiskSpace()\n"); if (IsListEmpty(&DiskEntry->PrimaryPartListHead)) { DPRINT1("No primary partition!\n"); /* Create a partition table that represents the empty disk */ NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PARTENTRY)); if (NewPartEntry == NULL) return; NewPartEntry->DiskEntry = DiskEntry; NewPartEntry->IsPartitioned = FALSE; NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment; NewPartEntry->SectorCount.QuadPart = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) - NewPartEntry->StartSector.QuadPart; DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); NewPartEntry->FormatState = Unformatted; InsertTailList(&DiskEntry->PrimaryPartListHead, &NewPartEntry->ListEntry); return; } /* Start partition at head 1, cylinder 0 */ LastStartSector = DiskEntry->SectorAlignment; LastSectorCount = 0ULL; LastUnusedSectorCount = 0ULL; Entry = DiskEntry->PrimaryPartListHead.Flink; while (Entry != &DiskEntry->PrimaryPartListHead) { PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->SectorCount.QuadPart != 0ULL) { LastUnusedSectorCount = PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount); if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) && LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment) { DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount); NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PARTENTRY)); if (NewPartEntry == NULL) return; NewPartEntry->DiskEntry = DiskEntry; NewPartEntry->IsPartitioned = FALSE; NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount; NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) - NewPartEntry->StartSector.QuadPart; DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); NewPartEntry->FormatState = Unformatted; /* Insert the table into the list */ InsertTailList(&PartEntry->ListEntry, &NewPartEntry->ListEntry); } LastStartSector = PartEntry->StartSector.QuadPart; LastSectorCount = PartEntry->SectorCount.QuadPart; } Entry = Entry->Flink; } /* Check for trailing unpartitioned disk space */ if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart) { LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment); if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment) { DPRINT1("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount); NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PARTENTRY)); if (NewPartEntry == NULL) return; NewPartEntry->DiskEntry = DiskEntry; NewPartEntry->IsPartitioned = FALSE; NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount; NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) - NewPartEntry->StartSector.QuadPart; DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); NewPartEntry->FormatState = Unformatted; /* Append the table to the list */ InsertTailList(&DiskEntry->PrimaryPartListHead, &NewPartEntry->ListEntry); } } if (DiskEntry->ExtendedPartition != NULL) { if (IsListEmpty(&DiskEntry->LogicalPartListHead)) { DPRINT1("No logical partition!\n"); /* Create a partition table entry that represents the empty extended partition */ NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PARTENTRY)); if (NewPartEntry == NULL) return; NewPartEntry->DiskEntry = DiskEntry; NewPartEntry->LogicalPartition = TRUE; NewPartEntry->IsPartitioned = FALSE; NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment; NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment; DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); NewPartEntry->FormatState = Unformatted; InsertTailList(&DiskEntry->LogicalPartListHead, &NewPartEntry->ListEntry); return; } /* Start partition at head 1, cylinder 0 */ LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment; LastSectorCount = 0ULL; LastUnusedSectorCount = 0ULL; Entry = DiskEntry->LogicalPartListHead.Flink; while (Entry != &DiskEntry->LogicalPartListHead) { PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->SectorCount.QuadPart != 0ULL) { LastUnusedSectorCount = PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount); if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) && LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment) { DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount); NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PARTENTRY)); if (NewPartEntry == NULL) return; NewPartEntry->DiskEntry = DiskEntry; NewPartEntry->LogicalPartition = TRUE; NewPartEntry->IsPartitioned = FALSE; NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount; NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) - NewPartEntry->StartSector.QuadPart; DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); NewPartEntry->FormatState = Unformatted; /* Insert the table into the list */ InsertTailList(&PartEntry->ListEntry, &NewPartEntry->ListEntry); } LastStartSector = PartEntry->StartSector.QuadPart; LastSectorCount = PartEntry->SectorCount.QuadPart; } Entry = Entry->Flink; } /* Check for trailing unpartitioned disk space */ if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart) { LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment); if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment) { DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount); NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PARTENTRY)); if (NewPartEntry == NULL) return; NewPartEntry->DiskEntry = DiskEntry; NewPartEntry->LogicalPartition = TRUE; NewPartEntry->IsPartitioned = FALSE; NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount; NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) - NewPartEntry->StartSector.QuadPart; DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); NewPartEntry->FormatState = Unformatted; /* Append the table to the list */ InsertTailList(&DiskEntry->LogicalPartListHead, &NewPartEntry->ListEntry); } } } DPRINT("ScanForUnpartitionedDiskSpace() done\n"); }
/* * @implemented */ DWORD WINAPI QueryDosDeviceA( LPCSTR lpDeviceName, LPSTR lpTargetPath, DWORD ucchMax ) { UNICODE_STRING DeviceNameU; UNICODE_STRING TargetPathU; ANSI_STRING TargetPathA; DWORD Length; DWORD CurrentLength; PWCHAR Buffer; if (lpDeviceName) { if (!RtlCreateUnicodeStringFromAsciiz (&DeviceNameU, (LPSTR)lpDeviceName)) { SetLastError (ERROR_NOT_ENOUGH_MEMORY); return 0; } } Buffer = RtlAllocateHeap (RtlGetProcessHeap (), 0, ucchMax * sizeof(WCHAR)); if (Buffer == NULL) { if (lpDeviceName) { RtlFreeHeap (RtlGetProcessHeap (), 0, DeviceNameU.Buffer); } SetLastError (ERROR_NOT_ENOUGH_MEMORY); return 0; } Length = QueryDosDeviceW (lpDeviceName ? DeviceNameU.Buffer : NULL, Buffer, ucchMax); if (Length != 0) { TargetPathA.Buffer = lpTargetPath; TargetPathU.Buffer = Buffer; ucchMax = Length; while (ucchMax) { CurrentLength = min (ucchMax, MAXUSHORT / 2); TargetPathU.MaximumLength = TargetPathU.Length = (USHORT)CurrentLength * sizeof(WCHAR); TargetPathA.Length = 0; TargetPathA.MaximumLength = (USHORT)CurrentLength; RtlUnicodeStringToAnsiString (&TargetPathA, &TargetPathU, FALSE); ucchMax -= CurrentLength; TargetPathA.Buffer += TargetPathA.Length; TargetPathU.Buffer += TargetPathU.Length / sizeof(WCHAR); } } RtlFreeHeap (RtlGetProcessHeap (), 0, Buffer); if (lpDeviceName) { RtlFreeHeap (RtlGetProcessHeap (), 0, DeviceNameU.Buffer); } return Length; }
/* * @implemented */ DWORD WINAPI ExpandEnvironmentStringsA ( LPCSTR lpSrc, LPSTR lpDst, DWORD nSize ) { ANSI_STRING Source; ANSI_STRING Destination; UNICODE_STRING SourceU; UNICODE_STRING DestinationU; NTSTATUS Status; ULONG Length = 0; RtlInitAnsiString (&Source, (LPSTR)lpSrc); Status = RtlAnsiStringToUnicodeString (&SourceU, &Source, TRUE); if (!NT_SUCCESS(Status)) { SetLastErrorByStatus (Status); return 0; } /* make sure we don't overflow the maximum ANSI_STRING size */ if (nSize > 0x7fff) nSize = 0x7fff; Destination.Length = 0; Destination.MaximumLength = (USHORT)nSize; Destination.Buffer = lpDst; DestinationU.Length = 0; DestinationU.MaximumLength = (USHORT)nSize * sizeof(WCHAR); DestinationU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (), 0, DestinationU.MaximumLength); if (DestinationU.Buffer == NULL) { RtlFreeUnicodeString(&SourceU); SetLastError(ERROR_NOT_ENOUGH_MEMORY); return 0; } Status = RtlExpandEnvironmentStrings_U (NULL, &SourceU, &DestinationU, &Length); RtlFreeUnicodeString (&SourceU); if (!NT_SUCCESS(Status)) { SetLastErrorByStatus (Status); if (Status != STATUS_BUFFER_TOO_SMALL) { RtlFreeHeap (RtlGetProcessHeap (), 0, DestinationU.Buffer); return 0; } } RtlUnicodeStringToAnsiString (&Destination, &DestinationU, FALSE); RtlFreeHeap (RtlGetProcessHeap (), 0, DestinationU.Buffer); return (Length / sizeof(WCHAR)); }
static VOID EnumerateBiosDiskEntries(VOID) { RTL_QUERY_REGISTRY_TABLE QueryTable[3]; WCHAR Name[120]; ULONG AdapterCount; ULONG DiskCount; NTSTATUS Status; PCM_INT13_DRIVE_PARAMETER Int13Drives; PBIOSDISKENTRY BiosDiskEntry; memset(QueryTable, 0, sizeof(QueryTable)); QueryTable[1].Name = L"Configuration Data"; QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine; Int13Drives = NULL; Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System", &QueryTable[1], (PVOID)&Int13Drives, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status); return; } AdapterCount = 0; while (1) { swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Name, &QueryTable[2], NULL, NULL); if (!NT_SUCCESS(Status)) { break; } swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Name, &QueryTable[2], NULL, NULL); if (NT_SUCCESS(Status)) { while (1) { swprintf(Name, L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Name, &QueryTable[2], NULL, NULL); if (!NT_SUCCESS(Status)) { RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives); return; } swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Name, &QueryTable[2], NULL, NULL); if (NT_SUCCESS(Status)) { QueryTable[0].Name = L"Identifier"; QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine; QueryTable[1].Name = L"Configuration Data"; QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine; DiskCount = 0; while (1) { BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY)); if (BiosDiskEntry == NULL) { break; } swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Name, QueryTable, (PVOID)BiosDiskEntry, NULL); if (!NT_SUCCESS(Status)) { RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry); break; } BiosDiskEntry->DiskNumber = DiskCount; BiosDiskEntry->Recognized = FALSE; if (DiskCount < Int13Drives[0].NumberDrives) { BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount]; } else { DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount); } InsertTailList(&BiosDiskListHead, &BiosDiskEntry->ListEntry); DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber); DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature); DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum); DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector); DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders); DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads); DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect); DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders); DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack); DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads); DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives); DiskCount++; } } RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives); return; } } AdapterCount++; } RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives); }
/* * @implemented */ BOOL WINAPI WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut) { UNICODE_STRING NamedPipeName, NewName, DevicePath, PipePrefix; ULONG NameLength; ULONG i; PWCHAR p; ULONG Type; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE FileHandle; IO_STATUS_BLOCK IoStatusBlock; ULONG WaitPipeInfoSize; PFILE_PIPE_WAIT_FOR_BUFFER WaitPipeInfo; /* Start by making a unicode string of the name */ TRACE("Sent path: %S\n", lpNamedPipeName); RtlCreateUnicodeString(&NamedPipeName, lpNamedPipeName); NameLength = NamedPipeName.Length / sizeof(WCHAR); /* All slashes must become backslashes */ for (i = 0; i < NameLength; i++) { /* Check and convert */ if (NamedPipeName.Buffer[i] == L'/') NamedPipeName.Buffer[i] = L'\\'; } /* Find the path type of the name we were given */ NewName = NamedPipeName; Type = RtlDetermineDosPathNameType_U(lpNamedPipeName); /* Check if this was a device path, ie : "\\.\pipe\name" */ if (Type == RtlPathTypeLocalDevice) { /* Make sure it's a valid prefix */ RtlInitUnicodeString(&PipePrefix, L"\\\\.\\pipe\\"); RtlPrefixString((PANSI_STRING)&PipePrefix, (PANSI_STRING)&NewName, TRUE); /* Move past it */ NewName.Buffer += 9; NewName.Length -= 9 * sizeof(WCHAR); /* Initialize the Dos Devices name */ TRACE("NewName: %wZ\n", &NewName); RtlInitUnicodeString(&DevicePath, L"\\DosDevices\\pipe\\"); } else if (Type == RtlPathTypeRootLocalDevice) { /* The path is \\server\\pipe\name; find the pipename itself */ p = &NewName.Buffer[2]; /* First loop to get past the server name */ do { /* Check if this is a backslash */ if (*p == L'\\') break; /* Check next */ p++; } while (*p); /* Now make sure the full name contains "pipe\" */ if ((*p) && !(_wcsnicmp(p + 1, L"pipe\\", sizeof("pipe\\")))) { /* Get to the pipe name itself now */ p += sizeof("pipe\\") - 1; } else { /* The name is invalid */ WARN("Invalid name!\n"); BaseSetLastNTError(STATUS_OBJECT_PATH_SYNTAX_BAD); return FALSE; } /* FIXME: Open \DosDevices\Unc\Server\Pipe\Name */ } else { WARN("Invalid path type\n"); BaseSetLastNTError(STATUS_OBJECT_PATH_SYNTAX_BAD); return FALSE; } /* Now calculate the total length of the structure and allocate it */ WaitPipeInfoSize = FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name[0]) + NewName.Length; WaitPipeInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, WaitPipeInfoSize); if (WaitPipeInfo == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } /* Initialize the object attributes */ TRACE("Opening: %wZ\n", &DevicePath); InitializeObjectAttributes(&ObjectAttributes, &DevicePath, OBJ_CASE_INSENSITIVE, NULL, NULL); /* Open the path */ Status = NtOpenFile(&FileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(Status)) { /* Fail; couldn't open */ WARN("Status: %lx\n", Status); BaseSetLastNTError(Status); RtlFreeUnicodeString(&NamedPipeName); RtlFreeHeap(RtlGetProcessHeap(), 0, WaitPipeInfo); return FALSE; } /* Check what timeout we got */ if (nTimeOut == NMPWAIT_USE_DEFAULT_WAIT) { /* Don't use a timeout */ WaitPipeInfo->TimeoutSpecified = FALSE; } else { /* Check if we should wait forever */ if (nTimeOut == NMPWAIT_WAIT_FOREVER) { /* Set the max */ WaitPipeInfo->Timeout.LowPart = 0; WaitPipeInfo->Timeout.HighPart = 0x80000000; } else { /* Convert to NT format */ WaitPipeInfo->Timeout.QuadPart = UInt32x32To64(-10000, nTimeOut); } /* In both cases, we do have a timeout */ WaitPipeInfo->TimeoutSpecified = TRUE; } /* Set the length and copy the name */ WaitPipeInfo->NameLength = NewName.Length; RtlCopyMemory(WaitPipeInfo->Name, NewName.Buffer, NewName.Length); /* Get rid of the full name */ RtlFreeUnicodeString(&NamedPipeName); /* Let NPFS know of our request */ Status = NtFsControlFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_PIPE_WAIT, WaitPipeInfo, WaitPipeInfoSize, NULL, 0); /* Free our pipe info data and close the handle */ RtlFreeHeap(RtlGetProcessHeap(), 0, WaitPipeInfo); NtClose(FileHandle); /* Check the status */ if (!NT_SUCCESS(Status)) { /* Failure to wait on the pipe */ WARN("Status: %lx\n", Status); BaseSetLastNTError (Status); return FALSE; } /* Success */ return TRUE; }
NTSTATUS LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg) { OBJECT_ATTRIBUTES ObjectAttributes; HANDLE ProcessHandle = NULL; PLIST_ENTRY SessionEntry; PLSAP_LOGON_SESSION CurrentSession; PLUID SessionList; ULONG i, Length, MemSize; PVOID ClientBaseAddress = NULL; NTSTATUS Status; TRACE("LsapEnumLogonSessions(%p)\n", RequestMsg); Length = SessionCount * sizeof(LUID); SessionList = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); if (SessionList == NULL) return STATUS_INSUFFICIENT_RESOURCES; i = 0; SessionEntry = SessionListHead.Flink; while (SessionEntry != &SessionListHead) { CurrentSession = CONTAINING_RECORD(SessionEntry, LSAP_LOGON_SESSION, Entry); RtlCopyLuid(&SessionList[i], &CurrentSession->LogonId); SessionEntry = SessionEntry->Flink; i++; } InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = NtOpenProcess(&ProcessHandle, PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, &ObjectAttributes, &RequestMsg->h.ClientId); if (!NT_SUCCESS(Status)) { TRACE("NtOpenProcess() failed (Status %lx)\n", Status); goto done; } TRACE("Length: %lu\n", Length); MemSize = Length; Status = NtAllocateVirtualMemory(ProcessHandle, &ClientBaseAddress, 0, &MemSize, MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status); goto done; } TRACE("MemSize: %lu\n", MemSize); TRACE("ClientBaseAddress: %p\n", ClientBaseAddress); Status = NtWriteVirtualMemory(ProcessHandle, ClientBaseAddress, SessionList, Length, NULL); if (!NT_SUCCESS(Status)) { TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status); goto done; } RequestMsg->EnumLogonSessions.Reply.LogonSessionCount = SessionCount; RequestMsg->EnumLogonSessions.Reply.LogonSessionBuffer = ClientBaseAddress; done: if (ProcessHandle != NULL) NtClose(ProcessHandle); if (SessionList != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, SessionList); return Status; }
/* * @implemented */ BOOL WINAPI PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage) { PFILE_PIPE_PEEK_BUFFER Buffer; IO_STATUS_BLOCK Iosb; ULONG BufferSize; ULONG BytesRead; NTSTATUS Status; /* Calculate the buffer space that we'll need and allocate it */ BufferSize = FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[nBufferSize]); Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize); if (Buffer == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } /* Tell the driver to seek */ Status = NtFsControlFile(hNamedPipe, NULL, NULL, NULL, &Iosb, FSCTL_PIPE_PEEK, NULL, 0, Buffer, BufferSize); if (Status == STATUS_PENDING) { /* Wait for npfs to be done, and update the status */ Status = NtWaitForSingleObject(hNamedPipe, FALSE, NULL); if (NT_SUCCESS(Status)) Status = Iosb.Status; } /* Overflow is success for us */ if (Status == STATUS_BUFFER_OVERFLOW) Status = STATUS_SUCCESS; /* If we failed */ if (!NT_SUCCESS(Status)) { /* Free the buffer and return failure */ RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); BaseSetLastNTError(Status); return FALSE; } /* Check if caller requested bytes available */ if (lpTotalBytesAvail) { /* Return bytes available */ *lpTotalBytesAvail = Buffer->ReadDataAvailable; } /* Calculate the bytes returned, minus our structure overhead */ BytesRead = (ULONG)(Iosb.Information - FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0])); ASSERT(BytesRead <= nBufferSize); /* Check if caller requested bytes read */ if (lpBytesRead) { /* Return the bytes read */ *lpBytesRead = BytesRead; } /* Check if caller requested bytes left */ if (lpBytesLeftThisMessage) { /* Calculate total minus what we returned and our structure overhead */ *lpBytesLeftThisMessage = Buffer->MessageLength - BytesRead; } /* Check if the caller wanted to see the actual data */ if (lpBuffer) { /* Give him what he wants */ RtlCopyMemory(lpBuffer, Buffer->Data, BytesRead); } /* Free the buffer */ RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); return TRUE; }
/* * @implemented */ HANDLE WINAPI CreateNamedPipeW(LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { UNICODE_STRING NamedPipeName; BOOL Result; NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE PipeHandle; ACCESS_MASK DesiredAccess; ULONG CreateOptions = 0; ULONG WriteModeMessage; ULONG ReadModeMessage; ULONG NonBlocking; IO_STATUS_BLOCK Iosb; ULONG ShareAccess = 0, Attributes; LARGE_INTEGER DefaultTimeOut; PSECURITY_DESCRIPTOR SecurityDescriptor = NULL; /* Check for valid instances */ if (nMaxInstances == 0 || nMaxInstances > PIPE_UNLIMITED_INSTANCES) { /* Fail */ SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; } /* Convert to NT syntax */ if (nMaxInstances == PIPE_UNLIMITED_INSTANCES) nMaxInstances = -1; /* Convert the name */ Result = RtlDosPathNameToNtPathName_U(lpName, &NamedPipeName, NULL, NULL); if (!Result) { /* Conversion failed */ SetLastError(ERROR_PATH_NOT_FOUND); return INVALID_HANDLE_VALUE; } TRACE("Pipe name: %wZ\n", &NamedPipeName); TRACE("Pipe name: %S\n", NamedPipeName.Buffer); /* Always case insensitive, check if we got extra attributes */ Attributes = OBJ_CASE_INSENSITIVE; if(lpSecurityAttributes) { /* We did; get the security descriptor */ SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor; /* And check if this is pipe's handle will beinheritable */ if (lpSecurityAttributes->bInheritHandle) Attributes |= OBJ_INHERIT; } /* Now we can initialize the object attributes */ InitializeObjectAttributes(&ObjectAttributes, &NamedPipeName, Attributes, NULL, SecurityDescriptor); /* Setup the default Desired Access */ DesiredAccess = SYNCHRONIZE | (dwOpenMode & (WRITE_DAC | WRITE_OWNER | ACCESS_SYSTEM_SECURITY)); /* Convert to NT Create Flags */ if (dwOpenMode & FILE_FLAG_WRITE_THROUGH) { CreateOptions |= FILE_WRITE_THROUGH; } if (!(dwOpenMode & FILE_FLAG_OVERLAPPED)) { CreateOptions |= FILE_SYNCHRONOUS_IO_NONALERT; } /* Handle all open modes */ if (dwOpenMode & PIPE_ACCESS_OUTBOUND) { ShareAccess |= FILE_SHARE_READ; DesiredAccess |= GENERIC_WRITE; } if (dwOpenMode & PIPE_ACCESS_INBOUND) { ShareAccess |= FILE_SHARE_WRITE; DesiredAccess |= GENERIC_READ; } /* Handle the type flags */ if (dwPipeMode & PIPE_TYPE_MESSAGE) { WriteModeMessage = FILE_PIPE_MESSAGE_TYPE; } else { WriteModeMessage = FILE_PIPE_BYTE_STREAM_TYPE; } /* Handle the mode flags */ if (dwPipeMode & PIPE_READMODE_MESSAGE) { ReadModeMessage = FILE_PIPE_MESSAGE_MODE; } else { ReadModeMessage = FILE_PIPE_BYTE_STREAM_MODE; } /* Handle the blocking mode */ if (dwPipeMode & PIPE_NOWAIT) { NonBlocking = FILE_PIPE_COMPLETE_OPERATION; } else { NonBlocking = FILE_PIPE_QUEUE_OPERATION; } /* Check if we have a timeout */ if (nDefaultTimeOut) { /* Convert the time to NT format */ DefaultTimeOut.QuadPart = UInt32x32To64(nDefaultTimeOut, -10000); } else { /* Use default timeout of 50 ms */ DefaultTimeOut.QuadPart = -500000; } /* Now create the pipe */ Status = NtCreateNamedPipeFile(&PipeHandle, DesiredAccess, &ObjectAttributes, &Iosb, ShareAccess, FILE_OPEN_IF, CreateOptions, WriteModeMessage, ReadModeMessage, NonBlocking, nMaxInstances, nInBufferSize, nOutBufferSize, &DefaultTimeOut); /* Normalize special error codes */ if ((Status == STATUS_INVALID_DEVICE_REQUEST) || (Status == STATUS_NOT_SUPPORTED)) { Status = STATUS_OBJECT_NAME_INVALID; } /* Free the name */ RtlFreeHeap(RtlGetProcessHeap(), 0, NamedPipeName.Buffer); /* Check status */ if (!NT_SUCCESS(Status)) { /* Failed to create it */ WARN("NtCreateNamedPipe failed (Status %x)!\n", Status); BaseSetLastNTError (Status); return INVALID_HANDLE_VALUE; } /* Return the handle */ return PipeHandle; }
/* * @implemented */ BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName) { FILE_DISPOSITION_INFORMATION FileDispInfo; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING NtPathU; HANDLE FileHandle; NTSTATUS Status; RTL_RELATIVE_NAME_U RelativeName; PWCHAR PathBuffer; FILE_ATTRIBUTE_TAG_INFORMATION FileTagInformation; /* Convert to NT path and get the relative name too */ if (!RtlDosPathNameToNtPathName_U(lpFileName, &NtPathU, NULL, &RelativeName)) { /* Bail out if the path name makes no sense */ SetLastError(ERROR_PATH_NOT_FOUND); return FALSE; } /* Save the path buffer in case we free it later */ PathBuffer = NtPathU.Buffer; /* If we have a relative name... */ if (RelativeName.RelativeName.Length) { /* Do a relative open with only the relative path set */ NtPathU = RelativeName.RelativeName; } else { /* Do a full path open with no containing directory */ RelativeName.ContainingDirectory = NULL; } /* Now open the directory name that was passed in */ InitializeObjectAttributes(&ObjectAttributes, &NtPathU, OBJ_CASE_INSENSITIVE, RelativeName.ContainingDirectory, NULL); Status = NtOpenFile(&FileHandle, DELETE | FILE_READ_ATTRIBUTES, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT); if (NT_SUCCESS(Status)) { /* Check if there's a reparse point associated with this file handle */ Status = NtQueryInformationFile(FileHandle, &IoStatusBlock, &FileTagInformation, sizeof(FileTagInformation), FileAttributeTagInformation); if ((NT_SUCCESS(Status)) && (FileTagInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && (FileTagInformation.ReparseTag != IO_REPARSE_TAG_MOUNT_POINT)) { /* There is, so now try to open it with reparse behavior */ NtClose(FileHandle); Status = NtOpenFile(&FileHandle, DELETE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT); if (!NT_SUCCESS(Status)) { /* We failed -- maybe whoever is handling this tag isn't there */ if (Status == STATUS_IO_REPARSE_TAG_NOT_HANDLED) { /* Try to open it for delete, without reparse behavior */ Status = NtOpenFile(&FileHandle, DELETE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT); } if (!NT_SUCCESS(Status)) { RtlReleaseRelativeName(&RelativeName); RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer); BaseSetLastNTError(Status); return FALSE; } } } else if (!(NT_SUCCESS(Status)) && (Status != STATUS_NOT_IMPLEMENTED) && (Status != STATUS_INVALID_PARAMETER)) { /* We had some critical error querying the attributes, bail out */ RtlReleaseRelativeName(&RelativeName); RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer); NtClose(FileHandle); BaseSetLastNTError(Status); return FALSE; } } else { /* It's possible that FILE_OPEN_REPARSE_POINT was not understood */ if (Status == STATUS_INVALID_PARAMETER) { /* Try opening the file normally, with reparse behavior */ Status = NtOpenFile(&FileHandle, DELETE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT); if (!NT_SUCCESS(Status)) { /* This failed too, fail */ RtlReleaseRelativeName(&RelativeName); RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer); BaseSetLastNTError(Status); return FALSE; } } else { /* Maybe we didn't have READ_ATTRIBUTE rights? */ if (Status != STATUS_ACCESS_DENIED) { /* Nope, it was something else, let's fail */ RtlReleaseRelativeName(&RelativeName); RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer); BaseSetLastNTError(Status); return FALSE; } /* Let's try again, without querying attributes */ Status = NtOpenFile(&FileHandle, DELETE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT); if (!NT_SUCCESS(Status)) { /* This failed too, so bail out */ RtlReleaseRelativeName(&RelativeName); RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer); BaseSetLastNTError(Status); return FALSE; } } } /* Ready to delete the file, so cleanup temporary data */ RtlReleaseRelativeName(&RelativeName); RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer); /* Ask for the file to be deleted */ FileDispInfo.DeleteFile = TRUE; Status = NtSetInformationFile(FileHandle, &IoStatusBlock, &FileDispInfo, sizeof(FILE_DISPOSITION_INFORMATION), FileDispositionInformation); NtClose(FileHandle); if (!NT_SUCCESS(Status)) { /* Deletion failed, tell the caller */ BaseSetLastNTError(Status); return FALSE; } /* Tell the caller deletion worked */ return TRUE; }
/* * @implemented */ HPEN APIENTRY ExtCreatePen(DWORD dwPenStyle, DWORD dwWidth, CONST LOGBRUSH *lplb, DWORD dwStyleCount, CONST DWORD *lpStyle) { PVOID lpPackedDIB = NULL; HPEN hPen = NULL; PBITMAPINFO pConvertedInfo = NULL; UINT ConvertedInfoSize = 0, lbStyle; BOOL Hit = FALSE; if ((dwPenStyle & PS_STYLE_MASK) == PS_USERSTYLE) { if(!lpStyle) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } } // This is an enhancement and prevents a call to kernel space. else if ((dwPenStyle & PS_STYLE_MASK) == PS_INSIDEFRAME && (dwPenStyle & PS_TYPE_MASK) != PS_GEOMETRIC) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } else if ((dwPenStyle & PS_STYLE_MASK) == PS_ALTERNATE && (dwPenStyle & PS_TYPE_MASK) != PS_COSMETIC) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } else { if (dwStyleCount || lpStyle) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } } lbStyle = lplb->lbStyle; if (lplb->lbStyle > BS_HATCHED) { if (lplb->lbStyle == BS_PATTERN) { pConvertedInfo = (PBITMAPINFO)lplb->lbHatch; if (!pConvertedInfo) return 0; } else { if ((lplb->lbStyle == BS_DIBPATTERN) || (lplb->lbStyle == BS_DIBPATTERNPT)) { if (lplb->lbStyle == BS_DIBPATTERN) { lbStyle = BS_DIBPATTERNPT; lpPackedDIB = GlobalLock((HGLOBAL)lplb->lbHatch); if (lpPackedDIB == NULL) return 0; } pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB, lplb->lbColor, &ConvertedInfoSize, TRUE); Hit = TRUE; // We converted DIB. } else pConvertedInfo = (PBITMAPINFO)lpStyle; } } else pConvertedInfo = (PBITMAPINFO)lplb->lbHatch; hPen = NtGdiExtCreatePen(dwPenStyle, dwWidth, lbStyle, lplb->lbColor, lplb->lbHatch, (ULONG_PTR)pConvertedInfo, dwStyleCount, (PULONG)lpStyle, ConvertedInfoSize, FALSE, NULL); if (lplb->lbStyle == BS_DIBPATTERN) GlobalUnlock((HGLOBAL)lplb->lbHatch); if (Hit) { if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); } return hPen; }
/*++ * @name CsrServerInitialization * @implemented NT4 * * The CsrServerInitialization routine is the native (not Server) entrypoint * of this Server DLL. It serves as the entrypoint for CSRSS. * * @param ArgumentCount * Number of arguments on the command line. * * @param Arguments * Array of arguments from the command line. * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise. * * @remarks None. * *--*/ NTSTATUS NTAPI CsrServerInitialization(IN ULONG ArgumentCount, IN PCHAR Arguments[]) { NTSTATUS Status = STATUS_SUCCESS; /* Create the Init Event */ Status = NtCreateEvent(&CsrInitializationEvent, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* Cache System Basic Information so we don't always request it */ Status = NtQuerySystemInformation(SystemBasicInformation, &CsrNtSysInfo, sizeof(SYSTEM_BASIC_INFORMATION), NULL); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* Save our Heap */ CsrHeap = RtlGetProcessHeap(); /* Set our Security Descriptor to protect the process */ Status = CsrSetProcessSecurity(); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* Set up Session Support */ Status = CsrInitializeNtSessionList(); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* Set up Process Support and allocate the CSR Root Process */ Status = CsrInitializeProcessStructure(); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* Parse the command line */ Status = CsrParseServerCommandLine(ArgumentCount, Arguments); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* Finish to initialize the CSR Root Process */ Status = CsrInitCsrRootProcess(); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrInitCsrRootProcess failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* Now initialize our API Port */ Status = CsrApiPortInitialize(); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* Initialize the API Port for SM communication */ Status = CsrSbApiPortInitialize(); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* We're all set! Connect to SM! */ Status = SmConnectToSm(&CsrSbApiPortName, CsrSbApiPort, IMAGE_SUBSYSTEM_WINDOWS_GUI, &CsrSmApiPort); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* Finito! Signal the event */ Status = NtSetEvent(CsrInitializationEvent, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* Close the event handle now */ NtClose(CsrInitializationEvent); /* Have us handle Hard Errors */ Status = NtSetDefaultHardErrorPort(CsrApiPort); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* Return status */ return Status; }
/* * @implemented */ DWORD WINAPI GetEnvironmentVariableA ( LPCSTR lpName, LPSTR lpBuffer, DWORD nSize ) { ANSI_STRING VarName; ANSI_STRING VarValue; UNICODE_STRING VarNameU; UNICODE_STRING VarValueU; NTSTATUS Status; /* initialize unicode variable name string */ RtlInitAnsiString (&VarName, (LPSTR)lpName); RtlAnsiStringToUnicodeString (&VarNameU, &VarName, TRUE); /* initialize ansi variable value string */ VarValue.Length = 0; VarValue.MaximumLength = (USHORT)nSize; VarValue.Buffer = lpBuffer; /* initialize unicode variable value string and allocate buffer */ VarValueU.Length = 0; if (nSize != 0) { VarValueU.MaximumLength = (USHORT)(nSize - 1) * sizeof(WCHAR); VarValueU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (), 0, nSize * sizeof(WCHAR)); if (VarValueU.Buffer != NULL) { /* NULL-terminate the buffer in any case! RtlQueryEnvironmentVariable_U only terminates it if MaximumLength < Length! */ VarValueU.Buffer[nSize - 1] = L'\0'; } } else { VarValueU.MaximumLength = 0; VarValueU.Buffer = NULL; } if (VarValueU.Buffer != NULL || nSize == 0) { /* get unicode environment variable */ Status = RtlQueryEnvironmentVariable_U (NULL, &VarNameU, &VarValueU); if (!NT_SUCCESS(Status)) { /* free unicode buffer */ RtlFreeHeap (RtlGetProcessHeap (), 0, VarValueU.Buffer); /* free unicode variable name string */ RtlFreeUnicodeString (&VarNameU); SetLastErrorByStatus (Status); if (Status == STATUS_BUFFER_TOO_SMALL) { return (VarValueU.Length / sizeof(WCHAR)) + 1; } else { return 0; } } /* convert unicode value string to ansi */ RtlUnicodeStringToAnsiString (&VarValue, &VarValueU, FALSE); if (VarValueU.Buffer != NULL) { /* free unicode buffer */ RtlFreeHeap (RtlGetProcessHeap (), 0, VarValueU.Buffer); } /* free unicode variable name string */ RtlFreeUnicodeString (&VarNameU); return (VarValueU.Length / sizeof(WCHAR)); } else { SetLastError (ERROR_NOT_ENOUGH_MEMORY); return 0; } }
NTSTATUS LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg) { OBJECT_ATTRIBUTES ObjectAttributes; HANDLE ProcessHandle = NULL; PLSAP_LOGON_SESSION Session; PSECURITY_LOGON_SESSION_DATA LocalSessionData; PVOID ClientBaseAddress = NULL; ULONG Length, MemSize; LPWSTR Ptr; NTSTATUS Status; TRACE("LsapGetLogonSessionData(%p)\n", RequestMsg); TRACE("LogonId: %lx\n", RequestMsg->GetLogonSessionData.Request.LogonId.LowPart); Session = LsapGetLogonSession(&RequestMsg->GetLogonSessionData.Request.LogonId); if (Session == NULL) return STATUS_NO_SUCH_LOGON_SESSION; Length = sizeof(SECURITY_LOGON_SESSION_DATA); /* Session->UserName.MaximumLength + Session->LogonDomain.MaximumLength + Session->AuthenticationPackage.MaximumLength + Session->LogonServer.MaximumLength + Session->DnsDomainName.MaximumLength + Session->Upn.MaximumLength; if (Session->Sid != NULL) RtlLengthSid(Session->Sid); */ TRACE("Length: %lu\n", Length); LocalSessionData = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); if (LocalSessionData == NULL) return STATUS_INSUFFICIENT_RESOURCES; Ptr = (LPWSTR)((ULONG_PTR)LocalSessionData + sizeof(SECURITY_LOGON_SESSION_DATA)); TRACE("LocalSessionData: %p Ptr: %p\n", LocalSessionData, Ptr); LocalSessionData->Size = sizeof(SECURITY_LOGON_SESSION_DATA); RtlCopyLuid(&LocalSessionData->LogonId, &RequestMsg->GetLogonSessionData.Request.LogonId); InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = NtOpenProcess(&ProcessHandle, PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, &ObjectAttributes, &RequestMsg->h.ClientId); if (!NT_SUCCESS(Status)) { TRACE("NtOpenProcess() failed (Status %lx)\n", Status); goto done; } MemSize = Length; Status = NtAllocateVirtualMemory(ProcessHandle, &ClientBaseAddress, 0, &MemSize, MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status); goto done; } TRACE("MemSize: %lu\n", MemSize); TRACE("ClientBaseAddress: %p\n", ClientBaseAddress); Status = NtWriteVirtualMemory(ProcessHandle, ClientBaseAddress, LocalSessionData, Length, NULL); if (!NT_SUCCESS(Status)) { TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status); goto done; } RequestMsg->GetLogonSessionData.Reply.SessionDataBuffer = ClientBaseAddress; done: if (ProcessHandle != NULL) NtClose(ProcessHandle); if (LocalSessionData != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSessionData); return Status; }
/* * @implemented */ LPSTR WINAPI GetEnvironmentStringsA ( VOID ) { UNICODE_STRING UnicodeString; ANSI_STRING AnsiString; PWCHAR EnvU; PWCHAR PtrU; ULONG Length; PCHAR EnvPtr = NULL; EnvU = (PWCHAR)(NtCurrentPeb ()->ProcessParameters->Environment); if (EnvU == NULL) return NULL; if (*EnvU == 0) return NULL; /* get environment size */ PtrU = EnvU; while (*PtrU) { while (*PtrU) PtrU++; PtrU++; } Length = (ULONG)(PtrU - EnvU); DPRINT("Length %lu\n", Length); /* allocate environment buffer */ EnvPtr = RtlAllocateHeap (RtlGetProcessHeap (), 0, Length + 1); if (EnvPtr == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; } DPRINT("EnvPtr %p\n", EnvPtr); /* convert unicode environment to ansi */ UnicodeString.MaximumLength = (USHORT)Length * sizeof(WCHAR) + sizeof(WCHAR); UnicodeString.Buffer = EnvU; AnsiString.MaximumLength = (USHORT)Length + 1; AnsiString.Length = 0; AnsiString.Buffer = EnvPtr; DPRINT ("UnicodeString.Buffer \'%S\'\n", UnicodeString.Buffer); while (*(UnicodeString.Buffer)) { UnicodeString.Length = wcslen (UnicodeString.Buffer) * sizeof(WCHAR); UnicodeString.MaximumLength = UnicodeString.Length + sizeof(WCHAR); if (UnicodeString.Length > 0) { AnsiString.Length = 0; AnsiString.MaximumLength = (USHORT)Length + 1 - (AnsiString.Buffer - EnvPtr); RtlUnicodeStringToAnsiString (&AnsiString, &UnicodeString, FALSE); AnsiString.Buffer += (AnsiString.Length + 1); UnicodeString.Buffer += ((UnicodeString.Length / sizeof(WCHAR)) + 1); } } *(AnsiString.Buffer) = 0; return EnvPtr; }
NTSTATUS NTAPI ConDrvWriteConsole(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer, IN BOOLEAN Unicode, IN PVOID StringBuffer, IN ULONG NumCharsToWrite, OUT PULONG NumCharsWritten OPTIONAL) { NTSTATUS Status = STATUS_SUCCESS; PWCHAR Buffer = NULL; ULONG Written = 0; ULONG Length; if (Console == NULL || ScreenBuffer == NULL /* || StringBuffer == NULL */) return STATUS_INVALID_PARAMETER; /* Validity checks */ ASSERT(Console == ScreenBuffer->Header.Console); ASSERT( (StringBuffer != NULL && NumCharsToWrite >= 0) || (StringBuffer == NULL && NumCharsToWrite == 0) ); // if (Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) if (Console->PauseFlags && Console->UnpauseEvent != NULL) { return STATUS_PENDING; } if (Unicode) { Buffer = StringBuffer; } else { Length = MultiByteToWideChar(Console->OutputCodePage, 0, (PCHAR)StringBuffer, NumCharsToWrite, NULL, 0); Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); if (Buffer) { MultiByteToWideChar(Console->OutputCodePage, 0, (PCHAR)StringBuffer, NumCharsToWrite, (PWCHAR)Buffer, Length); } else { Status = STATUS_NO_MEMORY; } } if (Buffer) { if (NT_SUCCESS(Status)) { Status = ConioWriteConsole(Console, ScreenBuffer, Buffer, NumCharsToWrite, TRUE); if (NT_SUCCESS(Status)) { Written = NumCharsToWrite; } } if (!Unicode) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); } if (NumCharsWritten) *NumCharsWritten = Written; return Status; }
static BOOLEAN InitializeFmIfsOnce(void) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING RegistryPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\SOFTWARE\\ReactOS\\ReactOS\\CurrentVersion\\IFS"); HANDLE hKey = NULL; PKEY_VALUE_FULL_INFORMATION Buffer; ULONG BufferSize = sizeof(KEY_VALUE_FULL_INFORMATION) + MAX_PATH; ULONG RequiredSize; ULONG i = 0; UNICODE_STRING Name; UNICODE_STRING Data; NTSTATUS Status; InitializeListHead(&ProviderListHead); /* Read IFS providers from HKLM\SOFTWARE\ReactOS\ReactOS\CurrentVersion\IFS */ InitializeObjectAttributes(&ObjectAttributes, &RegistryPath, 0, NULL, NULL); Status = NtOpenKey(&hKey, KEY_QUERY_VALUE, &ObjectAttributes); if (Status == STATUS_OBJECT_NAME_NOT_FOUND) return TRUE; else if (!NT_SUCCESS(Status)) return FALSE; Buffer = (PKEY_VALUE_FULL_INFORMATION)RtlAllocateHeap( RtlGetProcessHeap(), 0, BufferSize); if (!Buffer) { NtClose(hKey); return FALSE; } while (TRUE) { Status = NtEnumerateValueKey( hKey, i++, KeyValueFullInformation, Buffer, BufferSize, &RequiredSize); if (Status == STATUS_BUFFER_OVERFLOW) continue; else if (!NT_SUCCESS(Status)) break; else if (Buffer->Type != REG_SZ) continue; Name.Length = Name.MaximumLength = Buffer->NameLength; Name.Buffer = Buffer->Name; Data.Length = Data.MaximumLength = Buffer->DataLength; Data.Buffer = (PWCHAR)((ULONG_PTR)Buffer + Buffer->DataOffset); if (Data.Length > sizeof(WCHAR) && Data.Buffer[Data.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) Data.Length -= sizeof(WCHAR); AddProvider(&Name, Data.Buffer); } NtClose(hKey); RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); return TRUE; }
NTSTATUS NTAPI ConDrvWriteConsoleOutputString(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN CODE_TYPE CodeType, IN PVOID StringBuffer, IN ULONG NumCodesToWrite, IN PCOORD WriteCoord /*, OUT PCOORD EndCoord, OUT PULONG CodesWritten */) { NTSTATUS Status = STATUS_SUCCESS; PVOID WriteBuffer = NULL; PWCHAR tmpString = NULL; DWORD X, Y, Length; // , Written = 0; ULONG CodeSize; SMALL_RECT UpdateRect; PCHAR_INFO Ptr; if (Console == NULL || Buffer == NULL || WriteCoord == NULL /* || EndCoord == NULL || CodesWritten == NULL */) { return STATUS_INVALID_PARAMETER; } /* Validity checks */ ASSERT(Console == Buffer->Header.Console); ASSERT( (StringBuffer != NULL && NumCodesToWrite >= 0) || (StringBuffer == NULL && NumCodesToWrite == 0) ); switch (CodeType) { case CODE_ASCII: CodeSize = sizeof(CHAR); break; case CODE_UNICODE: CodeSize = sizeof(WCHAR); break; case CODE_ATTRIBUTE: CodeSize = sizeof(WORD); break; default: return STATUS_INVALID_PARAMETER; } if (CodeType == CODE_ASCII) { /* Convert the ASCII string into Unicode before writing it to the console */ Length = MultiByteToWideChar(Console->OutputCodePage, 0, (PCHAR)StringBuffer, NumCodesToWrite, NULL, 0); tmpString = WriteBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); if (WriteBuffer) { MultiByteToWideChar(Console->OutputCodePage, 0, (PCHAR)StringBuffer, NumCodesToWrite, (PWCHAR)WriteBuffer, Length); } else { Status = STATUS_NO_MEMORY; } } else { /* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */ WriteBuffer = StringBuffer; } if (WriteBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup; X = WriteCoord->X; Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; Length = NumCodesToWrite; // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work while (Length--) { // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; switch (CodeType) { case CODE_ASCII: case CODE_UNICODE: Ptr->Char.UnicodeChar = *(PWCHAR)WriteBuffer; break; case CODE_ATTRIBUTE: Ptr->Attributes = *(PWORD)WriteBuffer; break; } WriteBuffer = (PVOID)((ULONG_PTR)WriteBuffer + CodeSize); // ++Ptr; // Written++; if (++X == Buffer->ScreenBufferSize.X) { X = 0; if (++Y == Buffer->ScreenBufferSize.Y) { Y = 0; } } } if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) { ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite); ConioDrawRegion(Console, &UpdateRect); } // EndCoord->X = X; // EndCoord->Y = (Y + Buffer->ScreenBufferSize.Y - Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; Cleanup: if (tmpString) RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString); // CodesWritten = Written; return Status; }
static VOID AddPartitionToDisk( ULONG DiskNumber, PDISKENTRY DiskEntry, ULONG PartitionIndex, BOOLEAN LogicalPartition) { PPARTITION_INFORMATION PartitionInfo; PPARTENTRY PartEntry; PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex]; if (PartitionInfo->PartitionType == 0 || (LogicalPartition == TRUE && IsContainerPartition(PartitionInfo->PartitionType))) return; PartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PARTENTRY)); if (PartEntry == NULL) { return; } PartEntry->DiskEntry = DiskEntry; PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector; PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector; PartEntry->BootIndicator = PartitionInfo->BootIndicator; PartEntry->PartitionType = PartitionInfo->PartitionType; PartEntry->HiddenSectors = PartitionInfo->HiddenSectors; PartEntry->LogicalPartition = LogicalPartition; PartEntry->IsPartitioned = TRUE; PartEntry->PartitionNumber = PartitionInfo->PartitionNumber; PartEntry->PartitionIndex = PartitionIndex; if (IsContainerPartition(PartEntry->PartitionType)) { PartEntry->FormatState = Unformatted; if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL) DiskEntry->ExtendedPartition = PartEntry; } else if ((PartEntry->PartitionType == PARTITION_FAT_12) || (PartEntry->PartitionType == PARTITION_FAT_16) || (PartEntry->PartitionType == PARTITION_HUGE) || (PartEntry->PartitionType == PARTITION_XINT13) || (PartEntry->PartitionType == PARTITION_FAT32) || (PartEntry->PartitionType == PARTITION_FAT32_XINT13)) { #if 0 if (CheckFatFormat()) { PartEntry->FormatState = Preformatted; } else { PartEntry->FormatState = Unformatted; } #endif PartEntry->FormatState = Preformatted; } else if (PartEntry->PartitionType == PARTITION_EXT2) { #if 0 if (CheckExt2Format()) { PartEntry->FormatState = Preformatted; } else { PartEntry->FormatState = Unformatted; } #endif PartEntry->FormatState = Preformatted; } else if (PartEntry->PartitionType == PARTITION_IFS) { #if 0 if (CheckNtfsFormat()) { PartEntry->FormatState = Preformatted; } else if (CheckHpfsFormat()) { PartEntry->FormatState = Preformatted; } else { PartEntry->FormatState = Unformatted; } #endif PartEntry->FormatState = Preformatted; } else { PartEntry->FormatState = UnknownFormat; } if (LogicalPartition) InsertTailList(&DiskEntry->LogicalPartListHead, &PartEntry->ListEntry); else InsertTailList(&DiskEntry->PrimaryPartListHead, &PartEntry->ListEntry); }
NTSTATUS NTAPI SmpExecuteCommand(IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, OUT PHANDLE ProcessId, IN ULONG Flags) { NTSTATUS Status; UNICODE_STRING Arguments, Directory, FileName; /* There's no longer a debugging subsystem */ if (Flags & SMP_DEBUG_FLAG) return STATUS_SUCCESS; /* Parse the command line to see what execution flags are requested */ Status = SmpParseCommandLine(CommandLine, &Flags, &FileName, &Directory, &Arguments); if (!NT_SUCCESS(Status)) { /* Fail if we couldn't do that */ DPRINT1("SMSS: SmpParseCommandLine( %wZ ) failed - Status == %lx\n", CommandLine, Status); return Status; } /* Check if autochk is requested */ if (Flags & SMP_AUTOCHK_FLAG) { /* Run it */ Status = SmpInvokeAutoChk(&FileName, &Directory, &Arguments, Flags); } else if (Flags & SMP_SUBSYSTEM_FLAG) { Status = SmpLoadSubSystem(&FileName, &Directory, CommandLine, MuSessionId, ProcessId, Flags); } else if (Flags & SMP_INVALID_PATH) { /* An invalid image was specified, fail */ DPRINT1("SMSS: Image file (%wZ) not found\n", &FileName); Status = STATUS_OBJECT_NAME_NOT_FOUND; } else { /* An actual image name was present -- execute it */ Status = SmpExecuteImage(&FileName, &Directory, CommandLine, MuSessionId, Flags, NULL); } /* Free all the token parameters */ if (FileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer); if (Directory.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Directory.Buffer); if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer); /* Return to the caller */ if (!NT_SUCCESS(Status)) { DPRINT1("SMSS: Command '%wZ' failed - Status == %x\n", CommandLine, Status); } return Status; }
static VOID AddDiskToList( HANDLE FileHandle, ULONG DiskNumber) { DISK_GEOMETRY DiskGeometry; SCSI_ADDRESS ScsiAddress; PDISKENTRY DiskEntry; IO_STATUS_BLOCK Iosb; NTSTATUS Status; PPARTITION_SECTOR Mbr; PULONG Buffer; LARGE_INTEGER FileOffset; WCHAR Identifier[20]; ULONG Checksum; ULONG Signature; ULONG i; PLIST_ENTRY ListEntry; PBIOSDISKENTRY BiosDiskEntry; ULONG LayoutBufferSize; PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer; Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &DiskGeometry, sizeof(DISK_GEOMETRY)); if (!NT_SUCCESS(Status)) { return; } if (DiskGeometry.MediaType != FixedMedia && DiskGeometry.MediaType != RemovableMedia) { return; } Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, IOCTL_SCSI_GET_ADDRESS, NULL, 0, &ScsiAddress, sizeof(SCSI_ADDRESS)); if (!NT_SUCCESS(Status)) { return; } Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(RtlGetProcessHeap(), 0, DiskGeometry.BytesPerSector); if (Mbr == NULL) { return; } FileOffset.QuadPart = 0; Status = NtReadFile(FileHandle, NULL, NULL, NULL, &Iosb, (PVOID)Mbr, DiskGeometry.BytesPerSector, &FileOffset, NULL); if (!NT_SUCCESS(Status)) { RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr); DPRINT1("NtReadFile failed, status=%x\n", Status); return; } Signature = Mbr->Signature; /* Calculate the MBR checksum */ Checksum = 0; Buffer = (PULONG)Mbr; for (i = 0; i < 128; i++) { Checksum += Buffer[i]; } Checksum = ~Checksum + 1; swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature); DPRINT("Identifier: %S\n", Identifier); DiskEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DISKENTRY)); if (DiskEntry == NULL) { return; } // DiskEntry->Checksum = Checksum; // DiskEntry->Signature = Signature; DiskEntry->BiosFound = FALSE; /* Check if this disk has a valid MBR */ if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0) DiskEntry->NoMbr = TRUE; else DiskEntry->NoMbr = FALSE; /* Free Mbr sector buffer */ RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr); ListEntry = BiosDiskListHead.Flink; while (ListEntry != &BiosDiskListHead) { BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry); /* FIXME: * Compare the size from bios and the reported size from driver. * If we have more than one disk with a zero or with the same signatur * we must create new signatures and reboot. After the reboot, * it is possible to identify the disks. */ if (BiosDiskEntry->Signature == Signature && BiosDiskEntry->Checksum == Checksum && !BiosDiskEntry->Recognized) { if (!DiskEntry->BiosFound) { DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber; DiskEntry->BiosFound = TRUE; BiosDiskEntry->Recognized = TRUE; } else { } } ListEntry = ListEntry->Flink; } if (!DiskEntry->BiosFound) { #if 0 RtlFreeHeap(ProcessHeap, 0, DiskEntry); return; #else DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber); #endif } InitializeListHead(&DiskEntry->PrimaryPartListHead); InitializeListHead(&DiskEntry->LogicalPartListHead); DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart; DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder; DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack; DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector; DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders); DPRINT("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder); DPRINT("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack); DPRINT("BytesPerSector %I64u\n", DiskEntry->BytesPerSector); DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart * (ULONGLONG)DiskGeometry.TracksPerCylinder * (ULONGLONG)DiskGeometry.SectorsPerTrack; DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack; DiskEntry->CylinderAlignment = DiskGeometry.SectorsPerTrack * DiskGeometry.TracksPerCylinder; DPRINT1("SectorCount: %I64u\n", DiskEntry->SectorCount); DPRINT1("SectorAlignment: %lu\n", DiskEntry->SectorAlignment); DPRINT1("CylinderAlignment: %lu\n", DiskEntry->CylinderAlignment); DiskEntry->DiskNumber = DiskNumber; DiskEntry->Port = ScsiAddress.PortNumber; DiskEntry->Bus = ScsiAddress.PathId; DiskEntry->Id = ScsiAddress.TargetId; GetDriverName(DiskEntry); InsertAscendingList(&DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber); /* Allocate a layout buffer with 4 partition entries first */ LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION)); DiskEntry->LayoutBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, LayoutBufferSize); if (DiskEntry->LayoutBuffer == NULL) { DPRINT1("Failed to allocate the disk layout buffer!\n"); return; } for (;;) { DPRINT1("Buffer size: %lu\n", LayoutBufferSize); Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, IOCTL_DISK_GET_DRIVE_LAYOUT, NULL, 0, DiskEntry->LayoutBuffer, LayoutBufferSize); if (NT_SUCCESS(Status)) break; if (Status != STATUS_BUFFER_TOO_SMALL) { DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status); return; } LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION); NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, DiskEntry->LayoutBuffer, LayoutBufferSize); if (NewLayoutBuffer == NULL) { DPRINT1("Failed to reallocate the disk layout buffer!\n"); return; } DiskEntry->LayoutBuffer = NewLayoutBuffer; } DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount); #ifdef DUMP_PARTITION_TABLE DumpPartitionTable(DiskEntry); #endif if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 && DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 && DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != 0) { if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0) { DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack); } else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0) { DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector); } else { DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart); } } else { DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector); } if (DiskEntry->LayoutBuffer->PartitionCount == 0) { DiskEntry->NewDisk = TRUE; DiskEntry->LayoutBuffer->PartitionCount = 4; for (i = 0; i < 4; i++) DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE; } else { for (i = 0; i < 4; i++) { AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE); } for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4) { AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE); } } ScanForUnpartitionedDiskSpace(DiskEntry); }
NTSTATUS NTAPI SmpExecuteInitialCommand(IN ULONG MuSessionId, IN PUNICODE_STRING InitialCommand, IN HANDLE InitialCommandProcess, OUT PHANDLE ReturnPid) { NTSTATUS Status; RTL_USER_PROCESS_INFORMATION ProcessInfo; UNICODE_STRING Arguments, ImageFileDirectory, ImageFileName; ULONG Flags = 0; /* Check if we haven't yet connected to ourselves */ if (!SmApiPort) { /* Connect to ourselves, as a client */ Status = SmConnectToSm(0, 0, 0, &SmApiPort); if (!NT_SUCCESS(Status)) { DPRINT1("SMSS: Unable to connect to SM - Status == %lx\n", Status); return Status; } } /* Parse the initial command line */ Status = SmpParseCommandLine(InitialCommand, &Flags, &ImageFileName, &ImageFileDirectory, &Arguments); if (Flags & SMP_INVALID_PATH) { /* Fail if it doesn't exist */ DPRINT1("SMSS: Initial command image (%wZ) not found\n", &ImageFileName); if (ImageFileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer); return STATUS_OBJECT_NAME_NOT_FOUND; } /* And fail if any other reason is also true */ if (!NT_SUCCESS(Status)) { DPRINT1("SMSS: SmpParseCommandLine( %wZ ) failed - Status == %lx\n", InitialCommand, Status); return Status; } /* Execute the initial command -- but defer its full execution */ Status = SmpExecuteImage(&ImageFileName, &ImageFileDirectory, InitialCommand, MuSessionId, SMP_DEFERRED_FLAG, &ProcessInfo); /* Free any buffers we had lying around */ if (ImageFileName.Buffer) { RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer); } if (ImageFileDirectory.Buffer) { RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileDirectory.Buffer); } if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer); /* Bail out if we couldn't execute the initial command */ if (!NT_SUCCESS(Status)) return Status; /* Now duplicate the handle to this process */ Status = NtDuplicateObject(NtCurrentProcess(), ProcessInfo.ProcessHandle, NtCurrentProcess(), InitialCommandProcess, PROCESS_ALL_ACCESS, 0, 0); if (!NT_SUCCESS(Status)) { /* Kill it utterly if duplication failed */ DPRINT1("SMSS: DupObject Failed. Status == %lx\n", Status); NtTerminateProcess(ProcessInfo.ProcessHandle, Status); NtResumeThread(ProcessInfo.ThreadHandle, NULL); NtClose(ProcessInfo.ThreadHandle); NtClose(ProcessInfo.ProcessHandle); return Status; } /* Return PID to the caller, and set this as the initial command PID */ if (ReturnPid) *ReturnPid = ProcessInfo.ClientId.UniqueProcess; if (!MuSessionId) SmpInitialCommandProcessId = ProcessInfo.ClientId.UniqueProcess; /* Now call our server execution function to wrap up its initialization */ Status = SmExecPgm(SmApiPort, &ProcessInfo, FALSE); if (!NT_SUCCESS(Status)) DPRINT1("SMSS: SmExecPgm Failed. Status == %lx\n", Status); return Status; }
/* * @implemented */ BOOL WINAPI DefineDosDeviceW( DWORD dwFlags, LPCWSTR lpDeviceName, LPCWSTR lpTargetPath ) { ULONG ArgumentCount; ULONG BufferSize; BASE_API_MESSAGE ApiMessage; PBASE_DEFINE_DOS_DEVICE DefineDosDeviceRequest = &ApiMessage.Data.DefineDosDeviceRequest; PCSR_CAPTURE_BUFFER CaptureBuffer; NTSTATUS Status; UNICODE_STRING NtTargetPathU; UNICODE_STRING DeviceNameU; UNICODE_STRING DeviceUpcaseNameU; HANDLE hUser32; DEV_BROADCAST_VOLUME dbcv; BOOL Result = TRUE; DWORD dwRecipients; typedef long (WINAPI *BSM_type)(DWORD,LPDWORD,UINT,WPARAM,LPARAM); BSM_type BSM_ptr; if ( (dwFlags & 0xFFFFFFF0) || ((dwFlags & DDD_EXACT_MATCH_ON_REMOVE) && ! (dwFlags & DDD_REMOVE_DEFINITION)) ) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } ArgumentCount = 1; BufferSize = 0; if (! lpTargetPath) { RtlInitUnicodeString(&NtTargetPathU, NULL); } else { if (dwFlags & DDD_RAW_TARGET_PATH) { RtlInitUnicodeString(&NtTargetPathU, lpTargetPath); } else { if (! RtlDosPathNameToNtPathName_U(lpTargetPath, &NtTargetPathU, 0, 0)) { WARN("RtlDosPathNameToNtPathName_U() failed\n"); BaseSetLastNTError(STATUS_OBJECT_NAME_INVALID); return FALSE; } } ArgumentCount = 2; BufferSize += NtTargetPathU.Length; } RtlInitUnicodeString(&DeviceNameU, lpDeviceName); RtlUpcaseUnicodeString(&DeviceUpcaseNameU, &DeviceNameU, TRUE); BufferSize += DeviceUpcaseNameU.Length; CaptureBuffer = CsrAllocateCaptureBuffer(ArgumentCount, BufferSize); if (! CaptureBuffer) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); Result = FALSE; } else { DefineDosDeviceRequest->Flags = dwFlags; CsrCaptureMessageBuffer(CaptureBuffer, (PVOID)DeviceUpcaseNameU.Buffer, DeviceUpcaseNameU.Length, (PVOID*)&DefineDosDeviceRequest->DeviceName.Buffer); DefineDosDeviceRequest->DeviceName.Length = DeviceUpcaseNameU.Length; DefineDosDeviceRequest->DeviceName.MaximumLength = DeviceUpcaseNameU.Length; if (NtTargetPathU.Buffer) { CsrCaptureMessageBuffer(CaptureBuffer, (PVOID)NtTargetPathU.Buffer, NtTargetPathU.Length, (PVOID*)&DefineDosDeviceRequest->TargetPath.Buffer); } DefineDosDeviceRequest->TargetPath.Length = NtTargetPathU.Length; DefineDosDeviceRequest->TargetPath.MaximumLength = NtTargetPathU.Length; Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CaptureBuffer, CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepDefineDosDevice), sizeof(BASE_DEFINE_DOS_DEVICE)); CsrFreeCaptureBuffer(CaptureBuffer); if (!NT_SUCCESS(Status)) { WARN("CsrClientCallServer() failed (Status %lx)\n", Status); BaseSetLastNTError(Status); Result = FALSE; } else { if (! (dwFlags & DDD_NO_BROADCAST_SYSTEM) && DeviceUpcaseNameU.Length == 2 * sizeof(WCHAR) && DeviceUpcaseNameU.Buffer[1] == L':' && ( (DeviceUpcaseNameU.Buffer[0] - L'A') < 26 )) { hUser32 = LoadLibraryA("user32.dll"); if (hUser32) { BSM_ptr = (BSM_type) GetProcAddress(hUser32, "BroadcastSystemMessageW"); if (BSM_ptr) { dwRecipients = BSM_APPLICATIONS; dbcv.dbcv_size = sizeof(DEV_BROADCAST_VOLUME); dbcv.dbcv_devicetype = DBT_DEVTYP_VOLUME; dbcv.dbcv_reserved = 0; dbcv.dbcv_unitmask |= (1 << (DeviceUpcaseNameU.Buffer[0] - L'A')); dbcv.dbcv_flags = DBTF_NET; (void) BSM_ptr(BSF_SENDNOTIFYMESSAGE | BSF_FLUSHDISK, &dwRecipients, WM_DEVICECHANGE, (WPARAM)DBT_DEVICEARRIVAL, (LPARAM)&dbcv); } FreeLibrary(hUser32); } } } } if (NtTargetPathU.Buffer) { RtlFreeHeap(RtlGetProcessHeap(), 0, NtTargetPathU.Buffer); } RtlFreeUnicodeString(&DeviceUpcaseNameU); return Result; }
/* * @implemented */ BOOL WINAPI CheckTokenMembership(IN HANDLE ExistingTokenHandle, IN PSID SidToCheck, OUT PBOOL IsMember) { PISECURITY_DESCRIPTOR SecurityDescriptor = NULL; ACCESS_MASK GrantedAccess; struct { PRIVILEGE_SET PrivilegeSet; LUID_AND_ATTRIBUTES Privileges[4]; } PrivBuffer; ULONG PrivBufferSize = sizeof(PrivBuffer); GENERIC_MAPPING GenericMapping = { STANDARD_RIGHTS_READ, STANDARD_RIGHTS_WRITE, STANDARD_RIGHTS_EXECUTE, STANDARD_RIGHTS_ALL }; PACL Dacl; ULONG SidLen; HANDLE hToken = NULL; NTSTATUS Status, AccessStatus; /* doesn't return gracefully if IsMember is NULL! */ *IsMember = FALSE; SidLen = RtlLengthSid(SidToCheck); if (ExistingTokenHandle == NULL) { Status = NtOpenThreadToken(NtCurrentThread(), TOKEN_QUERY, FALSE, &hToken); if (Status == STATUS_NO_TOKEN) { /* we're not impersonating, open the primary token */ Status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &hToken); if (NT_SUCCESS(Status)) { HANDLE hNewToken = FALSE; BOOL DupRet; /* duplicate the primary token to create an impersonation token */ DupRet = DuplicateTokenEx(hToken, TOKEN_QUERY | TOKEN_IMPERSONATE, NULL, SecurityImpersonation, TokenImpersonation, &hNewToken); NtClose(hToken); if (!DupRet) { WARN("Failed to duplicate the primary token!\n"); return FALSE; } hToken = hNewToken; } } if (!NT_SUCCESS(Status)) { goto Cleanup; } } else { hToken = ExistingTokenHandle; } /* create a security descriptor */ SecurityDescriptor = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(SECURITY_DESCRIPTOR) + sizeof(ACL) + SidLen + sizeof(ACCESS_ALLOWED_ACE)); if (SecurityDescriptor == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } Status = RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* set the owner and group */ Status = RtlSetOwnerSecurityDescriptor(SecurityDescriptor, SidToCheck, FALSE); if (!NT_SUCCESS(Status)) { goto Cleanup; } Status = RtlSetGroupSecurityDescriptor(SecurityDescriptor, SidToCheck, FALSE); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* create the DACL */ Dacl = (PACL)(SecurityDescriptor + 1); Status = RtlCreateAcl(Dacl, sizeof(ACL) + SidLen + sizeof(ACCESS_ALLOWED_ACE), ACL_REVISION); if (!NT_SUCCESS(Status)) { goto Cleanup; } Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, 0x1, SidToCheck); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* assign the DACL to the security descriptor */ Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor, TRUE, Dacl, FALSE); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* it's time to perform the access check. Just use _some_ desired access right (same as for the ACE) and see if we're getting it granted. This indicates our SID is a member of the token. We however can't use a generic access right as those aren't mapped and return an error (STATUS_GENERIC_NOT_MAPPED). */ Status = NtAccessCheck(SecurityDescriptor, hToken, 0x1, &GenericMapping, &PrivBuffer.PrivilegeSet, &PrivBufferSize, &GrantedAccess, &AccessStatus); if (NT_SUCCESS(Status) && NT_SUCCESS(AccessStatus) && (GrantedAccess == 0x1)) { *IsMember = TRUE; } Cleanup: if (hToken != NULL && hToken != ExistingTokenHandle) { NtClose(hToken); } if (SecurityDescriptor != NULL) { RtlFreeHeap(RtlGetProcessHeap(), 0, SecurityDescriptor); } if (!NT_SUCCESS(Status)) { SetLastError(RtlNtStatusToDosError(Status)); return FALSE; } return TRUE; }
/*********************************************************************** * add_boot_rename_entry * * Adds an entry to the registry that is loaded when windows boots and * checks if there are some files to be removed or renamed/moved. * <fn1> has to be valid and <fn2> may be NULL. If both pointers are * non-NULL then the file is moved, otherwise it is deleted. The * entry of the registrykey is always appended with two zero * terminated strings. If <fn2> is NULL then the second entry is * simply a single 0-byte. Otherwise the second filename goes * there. The entries are prepended with \??\ before the path and the * second filename gets also a '!' as the first character if * MOVEFILE_REPLACE_EXISTING is set. After the final string another * 0-byte follows to indicate the end of the strings. * i.e.: * \??\D:\test\file1[0] * !\??\D:\test\file1_renamed[0] * \??\D:\Test|delete[0] * [0] <- file is to be deleted, second string empty * \??\D:\test\file2[0] * !\??\D:\test\file2_renamed[0] * [0] <- indicates end of strings * * or: * \??\D:\test\file1[0] * !\??\D:\test\file1_renamed[0] * \??\D:\Test|delete[0] * [0] <- file is to be deleted, second string empty * [0] <- indicates end of strings * */ static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags ) { static const WCHAR ValueName[] = {'P','e','n','d','i','n','g', 'F','i','l','e','R','e','n','a','m','e', 'O','p','e','r','a','t','i','o','n','s',0}; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager"); static const int info_size = FIELD_OFFSET( KEY_VALUE_PARTIAL_INFORMATION, Data ); OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING nameW, source_name, dest_name; KEY_VALUE_PARTIAL_INFORMATION *info; BOOL rc = FALSE; HANDLE Reboot = NULL; DWORD len1, len2; DWORD DestLen = 0; DWORD DataSize = 0; BYTE *Buffer = NULL; WCHAR *p; NTSTATUS Status; TRACE("add_boot_rename_entry( %S, %S, %d ) \n", source, dest, flags); if(dest) DestLen = wcslen(dest); if (!RtlDosPathNameToNtPathName_U( source, &source_name, NULL, NULL )) { SetLastError( ERROR_PATH_NOT_FOUND ); return FALSE; } dest_name.Buffer = NULL; if (DestLen && !RtlDosPathNameToNtPathName_U( dest, &dest_name, NULL, NULL )) { RtlFreeHeap( RtlGetProcessHeap(), 0, source_name.Buffer ); SetLastError( ERROR_PATH_NOT_FOUND ); return FALSE; } InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_OPENIF | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateKey(&Reboot, KEY_QUERY_VALUE | KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); if (Status == STATUS_ACCESS_DENIED) { Status = NtCreateKey( &Reboot, KEY_QUERY_VALUE | KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_BACKUP_RESTORE, NULL); } if (!NT_SUCCESS(Status)) { WARN("NtCreateKey() failed (Status 0x%lx)\n", Status); if (source_name.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, source_name.Buffer); if (dest_name.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, dest_name.Buffer); return FALSE; } len1 = source_name.Length + sizeof(WCHAR); if (DestLen) { len2 = dest_name.Length + sizeof(WCHAR); if (flags & MOVEFILE_REPLACE_EXISTING) len2 += sizeof(WCHAR); /* Plus 1 because of the leading '!' */ } else { len2 = sizeof(WCHAR); /* minimum is the 0 characters for the empty second string */ } RtlInitUnicodeString( &nameW, ValueName ); /* First we check if the key exists and if so how many bytes it already contains. */ Status = NtQueryValueKey( Reboot, &nameW, KeyValuePartialInformation, NULL, 0, &DataSize ); if ((Status == STATUS_BUFFER_OVERFLOW) || (Status == STATUS_BUFFER_TOO_SMALL)) { if (!(Buffer = HeapAlloc(GetProcessHeap(), 0, DataSize + len1 + len2 + sizeof(WCHAR)))) goto Quit; Status = NtQueryValueKey(Reboot, &nameW, KeyValuePartialInformation, Buffer, DataSize, &DataSize); if(!NT_SUCCESS(Status)) goto Quit; info = (KEY_VALUE_PARTIAL_INFORMATION *)Buffer; if (info->Type != REG_MULTI_SZ) goto Quit; if (DataSize > sizeof(info)) DataSize -= sizeof(WCHAR); /* remove terminating null (will be added back later) */ } else { DataSize = info_size; if (!(Buffer = HeapAlloc( GetProcessHeap(), 0, DataSize + len1 + len2 + sizeof(WCHAR) ))) goto Quit; } memcpy( Buffer + DataSize, source_name.Buffer, len1 ); DataSize += len1; p = (WCHAR *)(Buffer + DataSize); if (DestLen) { if (flags & MOVEFILE_REPLACE_EXISTING) *p++ = '!'; memcpy( p, dest_name.Buffer, len2 ); DataSize += len2; } else { *p = 0; DataSize += sizeof(WCHAR); } /* add final null */ p = (WCHAR *)(Buffer + DataSize); *p = 0; DataSize += sizeof(WCHAR); rc = NT_SUCCESS(NtSetValueKey(Reboot, &nameW, 0, REG_MULTI_SZ, Buffer + info_size, DataSize - info_size)); Quit: RtlFreeHeap(RtlGetProcessHeap(), 0, source_name.Buffer); if (dest_name.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, dest_name.Buffer); NtClose(Reboot); if(Buffer) HeapFree(GetProcessHeap(), 0, Buffer); return(rc); }
/* * @unimplemented */ PSID WINAPI GetSiteSidFromToken(IN HANDLE TokenHandle) { PTOKEN_GROUPS RestrictedSids; ULONG RetLen; UINT i; NTSTATUS Status; PSID PSiteSid = NULL; SID_IDENTIFIER_AUTHORITY InternetSiteAuthority = {SECURITY_INTERNETSITE_AUTHORITY}; Status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &RetLen); if (Status != STATUS_BUFFER_TOO_SMALL) { SetLastError(RtlNtStatusToDosError(Status)); return NULL; } RestrictedSids = (PTOKEN_GROUPS)RtlAllocateHeap(RtlGetProcessHeap(), 0, RetLen); if (RestrictedSids == NULL) { SetLastError(ERROR_OUTOFMEMORY); return NULL; } Status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, RestrictedSids, RetLen, &RetLen); if (NT_SUCCESS(Status)) { for (i = 0; i < RestrictedSids->GroupCount; i++) { SID* RSSid = RestrictedSids->Groups[i].Sid; if (RtlCompareMemory(&(RSSid->IdentifierAuthority), &InternetSiteAuthority, sizeof(SID_IDENTIFIER_AUTHORITY)) == sizeof(SID_IDENTIFIER_AUTHORITY)) { PSiteSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, RtlLengthSid((RestrictedSids-> Groups[i]).Sid)); if (PSiteSid == NULL) { SetLastError(ERROR_OUTOFMEMORY); } else { RtlCopySid(RtlLengthSid(RestrictedSids->Groups[i].Sid), PSiteSid, RestrictedSids->Groups[i].Sid); } break; } } } else { SetLastError(RtlNtStatusToDosError(Status)); } RtlFreeHeap(RtlGetProcessHeap(), 0, RestrictedSids); return PSiteSid; }
NTSTATUS SampRegQueryValue(IN HANDLE KeyHandle, IN LPCWSTR ValueName, OUT PULONG Type OPTIONAL, OUT PVOID Data OPTIONAL, IN OUT PULONG DataLength OPTIONAL) { PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; UNICODE_STRING Name; ULONG BufferLength = 0; NTSTATUS Status; RtlInitUnicodeString(&Name, ValueName); if (DataLength != NULL) BufferLength = *DataLength; BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data); /* Allocate memory for the value */ ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); if (ValueInfo == NULL) return STATUS_NO_MEMORY; /* Query the value */ Status = ZwQueryValueKey(KeyHandle, &Name, KeyValuePartialInformation, ValueInfo, BufferLength, &BufferLength); if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) { if (Type != NULL) *Type = ValueInfo->Type; if (DataLength != NULL) *DataLength = ValueInfo->DataLength; } /* Check if the caller wanted data back, and we got it */ if ((NT_SUCCESS(Status)) && (Data != NULL)) { /* Copy it */ RtlMoveMemory(Data, ValueInfo->Data, ValueInfo->DataLength); /* if the type is REG_SZ and data is not 0-terminated * and there is enough space in the buffer NT appends a \0 */ if (IsStringType(ValueInfo->Type) && ValueInfo->DataLength <= *DataLength - sizeof(WCHAR)) { WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength); if ((ptr > (WCHAR *)Data) && ptr[-1]) *ptr = 0; } } /* Free the memory and return status */ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo); if ((Data == NULL) && (Status == STATUS_BUFFER_OVERFLOW)) Status = STATUS_SUCCESS; return Status; }
static NTSTATUS Fat12WriteFAT(IN HANDLE FileHandle, IN ULONG SectorOffset, IN PFAT16_BOOT_SECTOR BootSector, IN OUT PFORMAT_CONTEXT Context) { IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status; PUCHAR Buffer; LARGE_INTEGER FileOffset; ULONG i; ULONG Size; ULONG Sectors; /* Allocate buffer */ Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(), 0, 32 * 1024); if (Buffer == NULL) return STATUS_INSUFFICIENT_RESOURCES; /* Zero the buffer */ RtlZeroMemory(Buffer, 32 * 1024); /* FAT cluster 0 & 1*/ Buffer[0] = 0xf8; /* Media type */ Buffer[1] = 0xff; Buffer[2] = 0xff; /* Write first sector of the FAT */ FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors) * BootSector->BytesPerSector; Status = NtWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, Buffer, BootSector->BytesPerSector, &FileOffset, NULL); if (!NT_SUCCESS(Status)) { DPRINT("NtWriteFile() failed (Status %lx)\n", Status); goto done; } UpdateProgress(Context, 1); /* Zero the begin of the buffer */ RtlZeroMemory(Buffer, 3); /* Zero the rest of the FAT */ Sectors = 32 * 1024 / BootSector->BytesPerSector; for (i = 1; i < (ULONG)BootSector->FATSectors; i += Sectors) { /* Zero some sectors of the FAT */ FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector; if (((ULONG)BootSector->FATSectors - i) <= Sectors) { Sectors = (ULONG)BootSector->FATSectors - i; } Size = Sectors * BootSector->BytesPerSector; Status = NtWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, Buffer, Size, &FileOffset, NULL); if (!NT_SUCCESS(Status)) { DPRINT("NtWriteFile() failed (Status %lx)\n", Status); goto done; } UpdateProgress(Context, Sectors); } done: /* Free the buffer */ RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); return Status; }