static BOOLEAN ReAllocBuffer( PUCHAR *Buffer, SIZE_T Size, SIZE_T *OldSizePtr, PCSTR Action) { PUCHAR NewBuffer; SIZE_T OldSize = *OldSizePtr; RtlFillMemory(*Buffer, OldSize, 0x7a); NewBuffer = RtlReAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, *Buffer, Size); if (!NewBuffer) { skip("RtlReAllocateHeap failed for size %lu (%s)\n", Size, Action); return FALSE; } *Buffer = NewBuffer; ok_hex(RtlSizeHeap(RtlGetProcessHeap(), 0, NewBuffer), Size); if (OldSize < Size) { ok(CheckBuffer(NewBuffer, OldSize, 0x7a), "CheckBuffer failed at size 0x%lx -> 0x%lx\n", OldSize, Size); ok(CheckBuffer(NewBuffer + OldSize, Size - OldSize, 0), "HEAP_ZERO_MEMORY not respected for 0x%lx -> 0x%lx\n", OldSize, Size); } else { ok(CheckBuffer(NewBuffer, Size, 0x7a), "CheckBuffer failed at size 0x%lx -> 0x%lx\n", OldSize, Size); } *OldSizePtr = Size; return TRUE; }
BOOL add_entry( LPINT ac, LPSTR **arg, LPCSTR entry) { LPSTR q; LPSTR *oldarg; q = RtlAllocateHeap(ProcessHeap, 0, strlen(entry) + 1); if (q == NULL) return FALSE; strcpy(q, entry); oldarg = *arg; *arg = RtlReAllocateHeap(ProcessHeap, 0, oldarg, (*ac + 2) * sizeof(LPSTR)); if (*arg == NULL) { RtlFreeHeap(ProcessHeap, 0, q); *arg = oldarg; return FALSE; } /* save new entry */ (*arg)[*ac] = q; (*arg)[++(*ac)] = NULL; return TRUE; }
/*************************************************************************** * add_load_order * * Adds an entry in the list of environment overrides. */ static void add_load_order( const module_loadorder_t *plo ) { int i; for(i = 0; i < env_list.count; i++) { if(!cmp_sort_func(plo, &env_list.order[i] )) { /* replace existing option */ env_list.order[i].loadorder = plo->loadorder; return; } } if (i >= env_list.alloc) { /* No space in current array, make it larger */ env_list.alloc += LOADORDER_ALLOC_CLUSTER; if (env_list.order) env_list.order = RtlReAllocateHeap(GetProcessHeap(), 0, env_list.order, env_list.alloc * sizeof(module_loadorder_t)); else env_list.order = RtlAllocateHeap(GetProcessHeap(), 0, env_list.alloc * sizeof(module_loadorder_t)); if(!env_list.order) { MESSAGE("Virtual memory exhausted\n"); exit(1); } } env_list.order[i].loadorder = plo->loadorder; env_list.order[i].modulename = plo->modulename; env_list.count++; }
PVOID WINAPI MemAlloc(IN HANDLE Heap, IN PVOID Ptr, IN ULONG Size) { PVOID pBuf = NULL; if(Size == 0 && Ptr == NULL) { return NULL; } if(Heap == NULL) { Heap = NtCurrentPeb()->ProcessHeap; } if(Size > 0) { if(Ptr == NULL) /* malloc */ pBuf = RtlAllocateHeap(Heap, 0, Size); else /* realloc */ pBuf = RtlReAllocateHeap(Heap, 0, Ptr, Size); } else /* free */ RtlFreeHeap(Heap, 0, Ptr); return pBuf; }
/* * @implemented */ void* __cdecl _expand(void* _ptr, size_t _size) { size_t nSize; nSize = ROUND_SIZE(_size); if (nSize<_size) return NULL; return RtlReAllocateHeap(RtlGetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, _ptr, nSize); }
PVOID CCGMemory::ReAlloc(PVOID pMemory, SIZE_T Size, ULONG Flags /* = 0 */) { PVOID pRealloc; pRealloc = RtlReAllocateHeap(m_HeapHandle, Flags, pMemory, Size); if (pRealloc == NULL) { RtlFreeHeap(m_HeapHandle, 0, pMemory); } return pRealloc; }
// _RtlReAllocateHeap - Calls to RtlReAllocateHeap are patched through to this // function. This function invokes the real RtlReAllocateHeap and then calls // VLD's reallocation tracking function. All arguments passed to this function // are passed on to the real RtlReAllocateHeap without modification. Pretty // much all memory re-allocations will eventually result in a call to // RtlReAllocateHeap, so this is where we finally remap the reallocated block. // // - heap (IN): Handle to the heap to reallocate memory from. // // - flags (IN): Heap control flags. // // - mem (IN): Pointer to the currently allocated block which is to be // reallocated. // // - size (IN): Size, in bytes, of the block to reallocate. // // Return Value: // // Returns the value returned by RtlReAllocateHeap. // LPVOID VisualLeakDetector::_RtlReAllocateHeap (HANDLE heap, DWORD flags, LPVOID mem, SIZE_T size) { PRINT_HOOKED_FUNCTION(); // Reallocate the block. LPVOID newmem = RtlReAllocateHeap(heap, flags, mem, size); if ((newmem == NULL) || !g_vld.enabled()) return newmem; if (!g_DbgHelp.IsLockedByCurrentThread()) { // skip dbghelp.dll calls CAPTURE_CONTEXT(); CaptureContext cc(RtlReAllocateHeap, size, context_); cc.Set(heap, mem, newmem, size); } return newmem; }
/* * @implemented */ void* __cdecl realloc(void* _ptr, size_t _size) { size_t nSize; if (_ptr == NULL) return malloc(_size); if (_size == 0) { free(_ptr); return NULL; } nSize = ROUND_SIZE(_size); /* check for integer overflow */ if (nSize<_size) return NULL; return RtlReAllocateHeap(RtlGetProcessHeap(), 0, _ptr, nSize); }
void * WINAPI redirect_RtlReAllocateHeap(HANDLE heap, ULONG flags, byte *ptr, SIZE_T size) { /* FIXME i#235: on x64 using dbghelp, SymLoadModule64 calls * kernel32!CreateFileW which calls * ntdll!RtlDosPathNameToRelativeNtPathName_U_WithStatus which calls * ntdll!RtlpDosPathNameToRelativeNtPathName_Ustr which directly calls * RtlAllocateHeap and passes peb->ProcessHeap: but then it's * kernel32!CreateFileW that calls RtlFreeHeap, so we end up seeing just a * free with no corresponding alloc. For now we handle by letting non-DR * addresses go natively. Xref the opposite problem with * RtlFreeUnicodeString, handled below. */ if (ptr == NULL) /* unlike realloc(), HeapReAlloc fails on NULL */ return NULL; if (redirect_heap_call(heap) && is_dynamo_address(ptr)) { byte *buf = NULL; if (TEST(HEAP_REALLOC_IN_PLACE_ONLY, flags)) { ASSERT_NOT_IMPLEMENTED(false); return NULL; } /* RtlReAllocateHeap does re-alloc 0-sized */ LOG(GLOBAL, LOG_LOADER, 2, "%s "PFX" "PIFX"\n", __FUNCTION__, ptr, size); buf = redirect_RtlAllocateHeap(heap, flags, size); if (buf != NULL) { size_t old_size = wrapped_dr_size(ptr); size_t min_size = MIN(old_size, size); memcpy(buf, ptr, min_size); redirect_RtlFreeHeap(heap, flags, ptr); } return (void *) buf; } else { void *res = RtlReAllocateHeap(heap, flags, ptr, size); LOG(GLOBAL, LOG_LOADER, 2, "native %s "PFX" "PIFX"\n", __FUNCTION__, res, size); return res; } }
PVOID NTAPI RtlDebugReAllocateHeap(HANDLE HeapPtr, ULONG Flags, PVOID Ptr, SIZE_T Size) { PHEAP Heap = (PHEAP)HeapPtr; SIZE_T AllocSize = 1; BOOLEAN HeapLocked = FALSE; PVOID Result = NULL; PHEAP_ENTRY HeapEntry; if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS) return RtlpPageHeapReAllocate(HeapPtr, Flags, Ptr, Size); if (Heap->Signature != HEAP_SIGNATURE) { DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature); return NULL; } /* Add settable user value flag */ Flags |= Heap->ForceFlags | HEAP_SETTABLE_USER_VALUE | HEAP_SKIP_VALIDATION_CHECKS; /* Calculate size */ if (Size) AllocSize = Size; AllocSize = ((AllocSize + Heap->AlignRound) & Heap->AlignMask) + sizeof(HEAP_ENTRY_EXTRA); /* Check if size didn't exceed max one */ if (AllocSize < Size || AllocSize > Heap->MaximumAllocationSize) { DPRINT1("HEAP: Too big allocation size %x (max allowed %x)\n", Size, Heap->MaximumAllocationSize); return NULL; } /* Lock the heap ourselves */ if (!(Flags & HEAP_NO_SERIALIZE)) { RtlEnterHeapLock(Heap->LockVariable, TRUE); HeapLocked = TRUE; /* Add no serialize flag so that the main routine won't try to acquire the lock again */ Flags |= HEAP_NO_SERIALIZE; } /* Validate the heap if necessary */ RtlpValidateHeap(Heap, FALSE); /* Get the existing heap entry */ HeapEntry = (PHEAP_ENTRY)Ptr - 1; /* Validate it */ if (RtlpValidateHeapEntry(Heap, HeapEntry)) { /* Call main routine to do the stuff */ Result = RtlReAllocateHeap(HeapPtr, Flags, Ptr, Size); if (Result) { /* Validate heap headers and then heap itself */ RtlpValidateHeapHeaders(Heap, TRUE); RtlpValidateHeap(Heap, FALSE); } } /* Release the lock */ if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable); return Result; }
static VOID CmdStartProcess(VOID) { #ifndef STANDALONE PCOMSPEC_INFO ComSpecInfo; #endif SIZE_T CmdLen; PNEXT_CMD DataStruct = (PNEXT_CMD)SEG_OFF_TO_PTR(getDS(), getDX()); DPRINT1("CmdStartProcess -- DS:DX = %04X:%04X (DataStruct = 0x%p)\n", getDS(), getDX(), DataStruct); /* Pause the VM */ EmulatorPause(); #ifndef STANDALONE /* Check whether we need to shell out now in case we were started by a 32-bit app */ ComSpecInfo = FindComSpecInfoByPsp(Sda->CurrentPsp); if (ComSpecInfo && ComSpecInfo->Terminated) { RemoveComSpecInfo(ComSpecInfo); DPRINT1("Exit DOS from start-app BOP\n"); setCF(1); goto Quit; } /* Clear the structure */ RtlZeroMemory(&CommandInfo, sizeof(CommandInfo)); /* Initialize the structure members */ CommandInfo.TaskId = SessionId; CommandInfo.VDMState = VDM_FLAG_DOS; CommandInfo.CmdLine = CmdLine; CommandInfo.CmdLen = sizeof(CmdLine); CommandInfo.AppName = AppName; CommandInfo.AppLen = sizeof(AppName); CommandInfo.PifFile = PifFile; CommandInfo.PifLen = sizeof(PifFile); CommandInfo.CurDirectory = CurDirectory; CommandInfo.CurDirectoryLen = sizeof(CurDirectory); CommandInfo.Desktop = Desktop; CommandInfo.DesktopLen = sizeof(Desktop); CommandInfo.Title = Title; CommandInfo.TitleLen = sizeof(Title); CommandInfo.Env = Env; CommandInfo.EnvLen = EnvSize; if (First) CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK; Command: if (Repeat) CommandInfo.VDMState |= VDM_FLAG_RETRY; Repeat = FALSE; /* Get the VDM command information */ DPRINT1("Calling GetNextVDMCommand in CmdStartProcess: wait for new VDM task...\n"); if (!GetNextVDMCommand(&CommandInfo)) { DPRINT1("CmdStartProcess - GetNextVDMCommand failed, retrying... last error = %d\n", GetLastError()); if (CommandInfo.EnvLen > EnvSize) { /* Expand the environment size */ EnvSize = CommandInfo.EnvLen; CommandInfo.Env = Env = RtlReAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Env, EnvSize); /* Repeat the request */ Repeat = TRUE; goto Command; } /* Shouldn't happen */ DisplayMessage(L"An unrecoverable failure happened from start-app BOP; exiting DOS."); setCF(1); goto Quit; } // FIXME: What happens if some other 32-bit app is killed while we are waiting there?? DPRINT1("CmdStartProcess - GetNextVDMCommand succeeded, start app...\n"); #else if (!First) { DPRINT1("Exit DOS from start-app BOP\n"); setCF(1); goto Quit; } #endif /* Compute the command line length, not counting the terminating "\r\n" */ CmdLen = strlen(CmdLine); if (CmdLen >= 2 && CmdLine[CmdLen - 2] == '\r') CmdLen -= 2; DPRINT1("Starting '%s' ('%.*s')...\n", AppName, CmdLen, CmdLine); /* Start the process */ // FIXME: Merge 'Env' with the master environment SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0) // FIXME: Environment RtlCopyMemory(SEG_OFF_TO_PTR(DataStruct->AppNameSeg, DataStruct->AppNameOff), AppName, MAX_PATH); *(PBYTE)(SEG_OFF_TO_PTR(DataStruct->CmdLineSeg, DataStruct->CmdLineOff)) = (BYTE)CmdLen; RtlCopyMemory(SEG_OFF_TO_PTR(DataStruct->CmdLineSeg, DataStruct->CmdLineOff + 1), CmdLine, DOS_CMDLINE_LENGTH); #ifndef STANDALONE /* Update console title if we run in a separate console */ if (SessionId != 0) SetConsoleTitleA(AppName); #endif First = FALSE; setCF(0); DPRINT1("App started!\n"); Quit: /* Resume the VM */ EmulatorResume(); }
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); }
/****************************************************************************** * NtQueryInformationToken [NTDLL.@] * ZwQueryInformationToken [NTDLL.@] * * NOTES * Buffer for TokenUser: * 0x00 TOKEN_USER the PSID field points to the SID * 0x08 SID * */ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass, PVOID tokeninfo, ULONG tokeninfolength, PULONG retlen ) { ULONG len; NTSTATUS status = STATUS_SUCCESS; TRACE("(%p,%d,%p,%ld,%p)\n", token,tokeninfoclass,tokeninfo,tokeninfolength,retlen); switch (tokeninfoclass) { case TokenOwner: len = sizeof(TOKEN_OWNER) + sizeof(SID); break; case TokenPrimaryGroup: len = sizeof(TOKEN_PRIMARY_GROUP); break; case TokenDefaultDacl: len = sizeof(TOKEN_DEFAULT_DACL); break; case TokenSource: len = sizeof(TOKEN_SOURCE); break; case TokenType: len = sizeof (TOKEN_TYPE); break; #if 0 case TokenImpersonationLevel: case TokenStatistics: #endif /* 0 */ default: len = 0; } if (retlen) *retlen = len; if (tokeninfolength < len) return STATUS_BUFFER_TOO_SMALL; switch (tokeninfoclass) { case TokenUser: SERVER_START_REQ( get_token_user ) { TOKEN_USER * tuser = tokeninfo; PSID sid = (PSID) (tuser + 1); DWORD sid_len = tokeninfolength < sizeof(TOKEN_USER) ? 0 : tokeninfolength - sizeof(TOKEN_USER); req->handle = token; wine_server_set_reply( req, sid, sid_len ); status = wine_server_call( req ); if (retlen) *retlen = reply->user_len + sizeof(TOKEN_USER); if (status == STATUS_SUCCESS) { tuser->User.Sid = sid; tuser->User.Attributes = 0; } } SERVER_END_REQ; break; case TokenGroups: { char stack_buffer[256]; unsigned int server_buf_len = sizeof(stack_buffer); void *buffer = stack_buffer; BOOLEAN need_more_memory = FALSE; /* we cannot work out the size of the server buffer required for the * input size, since there are two factors affecting how much can be * stored in the buffer - number of groups and lengths of sids */ do { SERVER_START_REQ( get_token_groups ) { TOKEN_GROUPS *groups = tokeninfo; req->handle = token; wine_server_set_reply( req, buffer, server_buf_len ); status = wine_server_call( req ); if (status == STATUS_BUFFER_TOO_SMALL) { if (buffer == stack_buffer) buffer = RtlAllocateHeap(GetProcessHeap(), 0, reply->user_len); else buffer = RtlReAllocateHeap(GetProcessHeap(), 0, buffer, reply->user_len); if (!buffer) return STATUS_NO_MEMORY; server_buf_len = reply->user_len; need_more_memory = TRUE; } else if (status == STATUS_SUCCESS) { struct token_groups *tg = buffer; unsigned int *attr = (unsigned int *)(tg + 1); ULONG i; const int non_sid_portion = (sizeof(struct token_groups) + tg->count * sizeof(unsigned long)); SID *sids = (SID *)((char *)tokeninfo + FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] )); ULONG needed_bytes = FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ) + reply->user_len - non_sid_portion; if (retlen) *retlen = needed_bytes; if (needed_bytes <= tokeninfolength) { groups->GroupCount = tg->count; memcpy( sids, (char *)buffer + non_sid_portion, reply->user_len - non_sid_portion ); for (i = 0; i < tg->count; i++) { groups->Groups[i].Attributes = attr[i]; groups->Groups[i].Sid = sids; sids = (SID *)((char *)sids + RtlLengthSid(sids)); } } else status = STATUS_BUFFER_TOO_SMALL; } else if (retlen) *retlen = 0; } SERVER_END_REQ; } while (need_more_memory); if (buffer != stack_buffer) RtlFreeHeap(GetProcessHeap(), 0, buffer); break; } case TokenPrimaryGroup: if (tokeninfo) { TOKEN_PRIMARY_GROUP *tgroup = tokeninfo; SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY}; RtlAllocateAndInitializeSid( &sid, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &(tgroup->PrimaryGroup)); } break; case TokenPrivileges: SERVER_START_REQ( get_token_privileges ) { TOKEN_PRIVILEGES *tpriv = tokeninfo; req->handle = token; if (tpriv && tokeninfolength > FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges )) wine_server_set_reply( req, &tpriv->Privileges, tokeninfolength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) ); status = wine_server_call( req ); if (retlen) *retlen = FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) + reply->len; if (tpriv) tpriv->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES); } SERVER_END_REQ; break; case TokenOwner: if (tokeninfo) { TOKEN_OWNER *owner = tokeninfo; PSID sid = (PSID) (owner + 1); SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY}; RtlInitializeSid(sid, &localSidAuthority, 1); *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID; owner->Owner = sid; } break; default: { ERR("Unhandled Token Information class %d!\n", tokeninfoclass); return STATUS_NOT_IMPLEMENTED; } } return status; }
LPVOID WINAPI HeapReAlloc( HANDLE heap, DWORD flags, LPVOID ptr, SIZE_T size ) { return RtlReAllocateHeap( heap, flags, ptr, size ); }
static ULONG NTAPI PnpEventThread(IN PVOID Parameter) { NTSTATUS Status; PPLUGPLAY_EVENT_BLOCK PnpEvent, NewPnpEvent; ULONG PnpEventSize; UNREFERENCED_PARAMETER(Parameter); PnpEventSize = 0x1000; PnpEvent = RtlAllocateHeap(ProcessHeap, 0, PnpEventSize); if (PnpEvent == NULL) { Status = STATUS_NO_MEMORY; goto Quit; } for (;;) { DPRINT("Calling NtGetPlugPlayEvent()\n"); /* Wait for the next PnP event */ Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize); /* Resize the buffer for the PnP event if it's too small */ if (Status == STATUS_BUFFER_TOO_SMALL) { PnpEventSize += 0x400; NewPnpEvent = RtlReAllocateHeap(ProcessHeap, 0, PnpEvent, PnpEventSize); if (NewPnpEvent == NULL) { Status = STATUS_NO_MEMORY; goto Quit; } PnpEvent = NewPnpEvent; continue; } if (!NT_SUCCESS(Status)) { DPRINT1("NtGetPlugPlayEvent() failed (Status 0x%08lx)\n", Status); goto Quit; } /* Process the PnP event */ DPRINT("Received PnP Event\n"); if (IsEqualGUID(&PnpEvent->EventGuid, &GUID_DEVICE_ENUMERATED)) { DeviceInstallParams* Params; ULONG len; ULONG DeviceIdLength; DPRINT("Device enumerated event: %S\n", PnpEvent->TargetDevice.DeviceIds); DeviceIdLength = wcslen(PnpEvent->TargetDevice.DeviceIds); if (DeviceIdLength) { /* Queue device install (will be dequeued by DeviceInstallThread) */ len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + (DeviceIdLength + 1) * sizeof(WCHAR); Params = RtlAllocateHeap(ProcessHeap, 0, len); if (Params) { wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds); RtlInterlockedPushEntrySList(&DeviceInstallListHead, &Params->ListEntry); NtSetEvent(hDeviceInstallListNotEmpty, NULL); } else { DPRINT1("Not enough memory (size %lu)\n", len); } } } else { DPRINT("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n", PnpEvent->EventGuid.Data1, PnpEvent->EventGuid.Data2, PnpEvent->EventGuid.Data3, PnpEvent->EventGuid.Data4[0], PnpEvent->EventGuid.Data4[1], PnpEvent->EventGuid.Data4[2], PnpEvent->EventGuid.Data4[3], PnpEvent->EventGuid.Data4[4], PnpEvent->EventGuid.Data4[5], PnpEvent->EventGuid.Data4[6], PnpEvent->EventGuid.Data4[7]); } /* Dequeue the current PnP event and signal the next one */ NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0); } Status = STATUS_SUCCESS; Quit: if (PnpEvent) RtlFreeHeap(ProcessHeap, 0, PnpEvent); NtTerminateThread(NtCurrentThread(), Status); return Status; }
int _cdecl main( int argc, char *argv[] ) { PVOID Heap, AllocatedBlock; ULONG i, n; PTEST_HEAP_ENTRY p; BOOLEAN Result; NTSTATUS Status; RTL_HEAP_USAGE Usage; PRTL_HEAP_USAGE_ENTRY pEntries; ULONG TagBaseIndex, Tag; ULONG TotalAllocated; RtlInitializeHeapManager(); memset( &Usage, 0, sizeof( Usage ) ); #if 0 HeapParameters.Length = sizeof( HeapParameters ); HeapParameters.DeCommitFreeBlockThreshold = 0x1000; HeapParameters.DeCommitTotalFreeThreshold = 0x4000; Heap = RtlCreateHeap( HEAP_GROWABLE | HEAP_NO_SERIALIZE, NULL, 256 * 4096, 4096, NULL, &HeapParameters ); #endif Heap = RtlCreateHeap( HEAP_GROWABLE | HEAP_NO_SERIALIZE | HEAP_CLASS_3, NULL, 0x100000, 0x1000, NULL, NULL ); if (Heap == NULL) { fprintf( stderr, "THEAP: Unable to create heap.\n" ); exit( 1 ); } fprintf( stderr, "THEAP: Created heap at %x\n", Heap ); DebugBreak(); TagBaseIndex = RtlCreateTagHeap( Heap, 0, L"THEAP!", L"!HeapName\0" L"Tag1\0" L"Tag2\0" L"Tag3\0" L"Tag4\0" L"Tag5\0" L"Tag6\0" L"Tag7\0" L"Tag8\0" L"Tag9\0" L"Tag10\0" L"Tag11\0" L"Tag12\0" L"Tag13\0" L"Tag14\0" L"Tag15\0" L"Tag16\0" L"Tag17\0" L"Tag18\0" L"Tag19\0" L"Tag20\0" L"Tag21\0" L"Tag22\0" L"Tag23\0" L"Tag24\0" L"Tag25\0" L"Tag26\0" L"Tag27\0" L"Tag28\0" L"Tag29\0" L"Tag30\0" L"Tag31\0" L"Tag32\0" L"Tag33\0" L"Tag34\0" L"Tag35\0" L"Tag36\0" L"Tag37\0" L"Tag38\0" L"Tag39\0" L"Tag40\0" L"Tag41\0" L"Tag42\0" L"Tag43\0" L"Tag44\0" L"Tag45\0" L"Tag46\0" L"Tag47\0" L"Tag48\0" L"Tag49\0" L"Tag50\0" L"Tag51\0" L"Tag52\0" L"Tag53\0" L"Tag54\0" L"Tag55\0" L"Tag56\0" L"Tag57\0" L"Tag58\0" L"Tag59\0" L"Tag60\0" ); NumberOfHeapEntries = 1000; HeapEntries = VirtualAlloc( NULL, NumberOfHeapEntries * sizeof( *HeapEntries ), MEM_COMMIT, PAGE_READWRITE ); if (HeapEntries == NULL) { fprintf( stderr, "THEAP: Unable to allocate space.\n" ); exit( 1 ); } RtlpHeapValidateOnCall=TRUE; // RtlpHeapStopOnAllocate=0x350f88; // RtlpHeapStopOnReAlloc=0x710040; TotalAllocated = 0; while (TotalAllocated < (2 * 1024 * 1024)) { i = RtlUniform( &Seed ) % NumberOfHeapEntries; if (RtlUniform( &Seed ) % 100) { n = RtlUniform( &Seed ) % REASONABLE_HEAP_ALLOC; } else { n = RtlUniform( &Seed ) % MAX_HEAP_ALLOC; } #if 0 Usage.Length = sizeof( Usage ); Status = RtlUsageHeap( Heap, HEAP_USAGE_ALLOCATED_BLOCKS , &Usage ); if (NT_SUCCESS( Status )) { if (Status == STATUS_MORE_ENTRIES) { pEntries = Usage.AddedEntries; while (pEntries) { fprintf( stderr, "Added: %08x %06x\n", pEntries->Address, pEntries->Size ); pEntries = pEntries->Next; } pEntries = Usage.RemovedEntries; while (pEntries) { fprintf( stderr, "Freed: %08x %06x\n", pEntries->Address, pEntries->Size ); pEntries = pEntries->Next; } } fprintf( stderr, "%08x %08x %08x %08x ", Usage.BytesAllocated, Usage.BytesCommitted, Usage.BytesReserved, Usage.BytesReservedMaximum ); } else { fprintf( stderr, "RtlUsageHeap failed with status %x\n", Status ); DebugBreak(); } if (i < 60) { Tag = (TagBaseIndex + i + 1) << 16; } else { Tag = 0; } #endif Tag = 0; p = &HeapEntries[ i ]; if (p->AllocatedBlock == NULL) { TotalAllocated += n; p->AllocatedBlock = RtlAllocateHeap( Heap, Tag, n ); fprintf( stderr, "Allocated %06x bytes at %08x\n", n, p->AllocatedBlock ); if (p->AllocatedBlock != NULL) { p->Size = n; } else { DebugBreak(); } } else if (RtlUniform( &Seed ) & 1) { TotalAllocated -= p->Size; TotalAllocated += n; AllocatedBlock = RtlReAllocateHeap( Heap, Tag, p->AllocatedBlock, n ); fprintf( stderr, "ReAlloced %06x bytes at %08x to %06x bytes at %08x\n", p->Size, p->AllocatedBlock, n, AllocatedBlock ); if (AllocatedBlock != NULL) { p->AllocatedBlock = AllocatedBlock; p->Size = n; } else { DebugBreak(); } } else { TotalAllocated -= p->Size; Result = RtlFreeHeap( Heap, 0, p->AllocatedBlock ); fprintf( stderr, "Freed %06x bytes at %08x\n", p->Size, p->AllocatedBlock ); if (Result) { p->AllocatedBlock = NULL; p->Size = 0; } else { DebugBreak(); } } } RtlResetHeap( Heap, 0 ); RtlValidateHeap( Heap, 0, NULL ); return 0; }