00025 :
00026
00027 Initialize
the address space of a VDM.
00028
00029 Arguments:
00030
00031 None,
00032
00033 Return Value:
00034
00035
NTSTATUS.
00036
00037 --*/
00038
00039 {
00040
NTSTATUS Status, StatusCopy;
00041 OBJECT_ATTRIBUTES
ObjectAttributes;
00042 UNICODE_STRING SectionName;
00043 UNICODE_STRING WorkString;
00044 ULONG ViewSize;
00045 LARGE_INTEGER ViewBase;
00046 PVOID BaseAddress;
00047 PVOID destination;
00048 HANDLE SectionHandle, RegistryHandle;
00049
PEPROCESS Process;
00050 ULONG ResultLength;
00051 ULONG
Index;
00052 PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor;
00053 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor;
00054 PKEY_VALUE_FULL_INFORMATION KeyValueBuffer;
00055 PCM_ROM_BLOCK BiosBlock;
00056 ULONG LastMappedAddress;
00057 PVDM_PROCESS_OBJECTS pVdmObjects =
NULL;
00058
USHORT PagedQuotaCharged = 0;
00059
USHORT NonPagedQuotaCharged = 0;
00060 HANDLE hThread;
00061
PVDM_TIB VdmTib;
00062
00063
00064
PAGED_CODE();
00065
00066
Status =
VdmpGetVdmTib(&VdmTib, VDMTIB_PROBE);
00067
00068
if (!
NT_SUCCESS(Status)) {
00069
return Status;
00070 }
00071
00072
if ((
KeI386MachineType & MACHINE_TYPE_PC_9800_COMPATIBLE) == 0) {
00073
00074
00075
00076
00077
00078
RtlInitUnicodeString(
00079 &SectionName,
00080 L
"\\Device\\PhysicalMemory"
00081 );
00082
00083 InitializeObjectAttributes(
00084 &ObjectAttributes,
00085 &SectionName,
00086 OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
00087 (HANDLE) NULL,
00088 (PSECURITY_DESCRIPTOR) NULL
00089 );
00090
00091
Status = ZwOpenSection(
00092 &SectionHandle,
00093 SECTION_ALL_ACCESS,
00094 &ObjectAttributes
00095 );
00096
00097
if (!
NT_SUCCESS(Status)) {
00098
00099
return Status;
00100
00101 }
00102
00103
00104
00105
00106
00107 BaseAddress = 0;
00108 destination = 0;
00109 ViewSize = 0x1000;
00110 ViewBase.LowPart = 0;
00111 ViewBase.HighPart = 0;
00112
00113
Status = ZwMapViewOfSection(
00114 SectionHandle,
00115 NtCurrentProcess(),
00116 &BaseAddress,
00117 0,
00118 ViewSize,
00119 &ViewBase,
00120 &ViewSize,
00121 ViewUnmap,
00122 0,
00123 PAGE_READWRITE
00124 );
00125
00126
if (!
NT_SUCCESS(Status)) {
00127 ZwClose(SectionHandle);
00128
return Status;
00129 }
00130
00131
00132
00133
00134
00135 StatusCopy = STATUS_SUCCESS;
00136
try {
00137 RtlMoveMemory(
00138 destination,
00139 BaseAddress,
00140 ViewSize
00141 );
00142 }
00143 except(
ExSystemExceptionFilter()) {
00144 StatusCopy = GetExceptionCode();
00145 }
00146
00147
00148
Status = ZwUnmapViewOfSection(
00149 NtCurrentProcess(),
00150 BaseAddress
00151 );
00152
00153
if (!
NT_SUCCESS(Status) || !
NT_SUCCESS(StatusCopy)) {
00154 ZwClose(SectionHandle);
00155
return (
NT_SUCCESS(Status) ? StatusCopy :
Status);
00156 }
00157
00158
00159
00160
00161
00162 BaseAddress = (PVOID) 0x000C0000;
00163 ViewSize = 0x40000;
00164 ViewBase.LowPart = 0x000C0000;
00165 ViewBase.HighPart = 0;
00166
00167
00168
00169
00170
00171
00172
00173
00174
Status = ZwFreeVirtualMemory(
00175 NtCurrentProcess(),
00176 &BaseAddress,
00177 &ViewSize,
00178 MEM_RELEASE
00179 );
00180
00181
00182
00183
00184
00185
if (!
NT_SUCCESS(Status)) {
00186 ZwClose(SectionHandle);
00187
return Status;
00188
00189 }
00190
00191
00192
00193
00194
00195 InitializeObjectAttributes(
00196 &ObjectAttributes,
00197 &CmRegistryMachineHardwareDescriptionSystemName,
00198 OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
00199 (HANDLE)NULL,
00200 NULL
00201 );
00202
00203
Status = ZwOpenKey(
00204 &RegistryHandle,
00205 KEY_READ,
00206 &ObjectAttributes
00207 );
00208
00209
if (!
NT_SUCCESS(Status)) {
00210 ZwClose(SectionHandle);
00211
return Status;
00212 }
00213
00214
00215
00216
00217
00218 KeyValueBuffer =
ExAllocatePoolWithTag(
00219 PagedPool,
00220 KEY_VALUE_BUFFER_SIZE,
00221 ' MDV'
00222 );
00223
00224
if (KeyValueBuffer ==
NULL) {
00225 ZwClose(RegistryHandle);
00226 ZwClose(SectionHandle);
00227
return STATUS_NO_MEMORY;
00228 }
00229
00230
00231
00232
00233
00234
RtlInitUnicodeString(
00235 &WorkString,
00236 L
"Configuration Data"
00237 );
00238
00239
Status = ZwQueryValueKey(
00240 RegistryHandle,
00241 &WorkString,
00242 KeyValueFullInformation,
00243 KeyValueBuffer,
00244 KEY_VALUE_BUFFER_SIZE,
00245 &ResultLength
00246 );
00247
00248
if (!
NT_SUCCESS(Status)) {
00249 ZwClose(RegistryHandle);
00250
ExFreePool(KeyValueBuffer);
00251 ZwClose(SectionHandle);
00252
return Status;
00253 }
00254
00255 ResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)
00256 ((PUCHAR) KeyValueBuffer + KeyValueBuffer->DataOffset);
00257
00258
if ((KeyValueBuffer->DataLength <
sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) ||
00259 (ResourceDescriptor->PartialResourceList.Count < 2)
00260 ) {
00261 ZwClose(RegistryHandle);
00262
ExFreePool(KeyValueBuffer);
00263 ZwClose(SectionHandle);
00264
00265
return STATUS_SUCCESS;
00266 }
00267
00268 PartialResourceDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
00269 ((PUCHAR)ResourceDescriptor +
00270
sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
00271 ResourceDescriptor->PartialResourceList.PartialDescriptors[0]
00272 .u.DeviceSpecificData.DataSize);
00273
00274
00275
if (KeyValueBuffer->DataLength < ((PUCHAR)PartialResourceDescriptor -
00276 (PUCHAR)ResourceDescriptor +
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)
00277 +
sizeof(CM_ROM_BLOCK))
00278 ) {
00279 ZwClose(RegistryHandle);
00280
ExFreePool(KeyValueBuffer);
00281 ZwClose(SectionHandle);
00282
return STATUS_ILL_FORMED_SERVICE_ENTRY;
00283 }
00284
00285
00286 BiosBlock = (PCM_ROM_BLOCK)((PUCHAR)PartialResourceDescriptor +
00287
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
00288
00289
Index = PartialResourceDescriptor->u.DeviceSpecificData.DataSize /
00290
sizeof(CM_ROM_BLOCK);
00291
00292
00293
00294
00295
00296
00297
00298
00299 LastMappedAddress = 0xC0000;
00300
00301
while (
Index) {
00302
#if 0
00303
DbgPrint(
00304
"Bios Block, PhysAddr = %lx, size = %lx\n",
00305 BiosBlock->Address,
00306 BiosBlock->Size
00307 );
00308
#endif
00309
if ((
Index > 1) &&
00310 ((BiosBlock->Address + BiosBlock->Size) == BiosBlock[1].Address)
00311 ) {
00312
00313
00314
00315 BiosBlock[1].Address = BiosBlock[0].Address;
00316 BiosBlock[1].Size += BiosBlock[0].Size;
00317
Index--;
00318 BiosBlock++;
00319
continue;
00320 }
00321
00322 BaseAddress = (PVOID)(BiosBlock->Address);
00323 ViewSize = BiosBlock->Size;
00324
00325
if ((ULONG)BaseAddress < LastMappedAddress) {
00326
if (ViewSize > (LastMappedAddress - (ULONG)BaseAddress)) {
00327 ViewSize = ViewSize - (LastMappedAddress - (ULONG)BaseAddress);
00328 BaseAddress = (PVOID)LastMappedAddress;
00329 }
else {
00330 ViewSize = 0;
00331 }
00332 }
00333
00334 ViewBase.LowPart = (ULONG)BaseAddress;
00335
00336
if (ViewSize > 0) {
00337
00338
Status = ZwMapViewOfSection(
00339 SectionHandle,
00340 NtCurrentProcess(),
00341 &BaseAddress,
00342 0,
00343 ViewSize,
00344 &ViewBase,
00345 &ViewSize,
00346 ViewUnmap,
00347 MEM_DOS_LIM,
00348 PAGE_READWRITE
00349 );
00350
00351
if (!
NT_SUCCESS(Status)) {
00352
break;
00353 }
00354
00355 LastMappedAddress = (ULONG)BaseAddress + ViewSize;
00356 }
00357
00358
Index--;
00359 BiosBlock++;
00360 }
00361
00362
00363
00364
00365
00366 ZwClose(SectionHandle);
00367 ZwClose(RegistryHandle);
00368
ExFreePool(KeyValueBuffer);
00369
00370 }
else {
00371
00372
00373
00374
00375
00376
Status = STATUS_SUCCESS;
00377 }
00378
00379
00380
00381
00382
00383 Process =
PsGetCurrentProcess();
00384 Process->
Pcb.VdmFlag =
TRUE;
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
try {
00398
00399 Process->
VdmObjects =
ExAllocatePoolWithTag(
00400 NonPagedPool,
00401
sizeof(VDM_PROCESS_OBJECTS),
00402 ' MDV'
00403 );
00404
00405
if (Process->
VdmObjects ==
NULL) {
00406
return STATUS_NO_MEMORY;
00407 }
00408
00409
00410
00411
00412
00413
00414
PsChargePoolQuota(Process, NonPagedPool,
sizeof(VDM_PROCESS_OBJECTS));
00415 NonPagedQuotaCharged =
sizeof(VDM_PROCESS_OBJECTS);
00416
00417 RtlZeroMemory( Process->
VdmObjects,
sizeof(VDM_PROCESS_OBJECTS));
00418 pVdmObjects = Process->
VdmObjects;
00419
ExInitializeFastMutex(&pVdmObjects->DelayIntFastMutex);
00420
KeInitializeSpinLock(&pVdmObjects->DelayIntSpinLock);
00421 InitializeListHead(&pVdmObjects->DelayIntListHead);
00422
00423 pVdmObjects->pIcaUserData =
ExAllocatePoolWithTag(
00424 PagedPool,
00425
sizeof(VDMICAUSERDATA),
00426 ' MDV'
00427 );
00428
00429
if (pVdmObjects->pIcaUserData ==
NULL) {
00430
Status = STATUS_NO_MEMORY;
00431 }
else {
00432
00433
00434
00435
00436
00437
PsChargePoolQuota(
00438 Process,
00439 PagedPool,
00440
sizeof(VDMICAUSERDATA)
00441 );
00442 PagedQuotaCharged =
sizeof(VDMICAUSERDATA);
00443
00444 RtlZeroMemory( pVdmObjects->pIcaUserData,
sizeof(VDMICAUSERDATA));
00445
00446
00447
00448
00449
00450
00451
00452
ProbeForRead(pIcaUserData,
sizeof(VDMICAUSERDATA),
sizeof(UCHAR));
00453 *pVdmObjects->pIcaUserData = *pIcaUserData;
00454
00455
00456
00457
00458
00459 pIcaUserData = pVdmObjects->pIcaUserData;
00460
00461
ProbeForWriteHandle(pIcaUserData->phWowIdleEvent);
00462
00463
ProbeForWrite(
00464 pIcaUserData->pIcaLock,
00465
sizeof(RTL_CRITICAL_SECTION),
00466
sizeof(UCHAR)
00467 );
00468
00469
ProbeForWrite(
00470 pIcaUserData->pIcaMaster,
00471
sizeof(VDMVIRTUALICA),
00472
sizeof(UCHAR)
00473 );
00474
00475
ProbeForWrite(
00476 pIcaUserData->pIcaSlave,
00477
sizeof(VDMVIRTUALICA),
00478
sizeof(UCHAR)
00479 );
00480
00481
ProbeForWriteUlong(pIcaUserData->pIretHooked);
00482
ProbeForWriteUlong(pIcaUserData->pDelayIrq);
00483
ProbeForWriteUlong(pIcaUserData->pUndelayIrq);
00484
ProbeForWriteUlong(pIcaUserData->pDelayIret);
00485
00486
00487
00488
00489
00490
00491
00492
00493 InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
00494
Status = ZwOpenThread(&hThread,
00495 THREAD_QUERY_INFORMATION,
00496 &ObjectAttributes,
00497 &NtCurrentTeb()->ClientId
00498 );
00499
00500
if (
NT_SUCCESS(Status)) {
00501 pVdmObjects->MainThread =
PsGetCurrentThread();
00502 }
00503
00504
00505 pVdmObjects->VdmTib = VdmTib;
00506 }
00507
00508 } except(
ExSystemExceptionFilter()) {
00509
Status = GetExceptionCode();
00510 }
00511
00512
00513
if (!
NT_SUCCESS(Status)) {
00514
if (pVdmObjects) {
00515
if (pVdmObjects->pIcaUserData) {
00516
ExFreePool(pVdmObjects->pIcaUserData);
00517 }
00518
ExFreePool(pVdmObjects);
00519 }
00520 Process->
VdmObjects =
NULL;
00521
00522
00523
00524
00525
PsReturnPoolQuota(Process, NonPagedPool, NonPagedQuotaCharged);
00526
PsReturnPoolQuota(Process, PagedPool, PagedQuotaCharged);
00527 }
00528
00529
00530
00531
00532
00533
if ((
KeI386MachineType & MACHINE_TYPE_PC_9800_COMPATIBLE) == 0) {
00534
00535
#ifdef WHEN_IO_DISPATCHING_IMPROVED
00536
00537
00538
00539
00540 VdmInitializePrinter ();
00541
#endif
00542
}
00543
00544
return Status;
00545
00546 }
}