00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
#include "iop.h"
00028
#pragma hdrstop
00029
00030
#ifdef POOL_TAGGING
00031
#undef ExAllocatePool
00032
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'iepP')
00033
#endif
00034
00035 #define EISA_DEVICE_NODE_NAME L"EisaResources"
00036 #define BUFFER_LENGTH 50
00037
00038
NTSTATUS
00039
EisaGetEisaDevicesResources (
00040 OUT PCM_RESOURCE_LIST *ResourceList,
00041 OUT PULONG ResourceLength
00042 );
00043
00044
NTSTATUS
00045
EisaBuildSlotsResources (
00046 IN ULONG SlotMasks,
00047 IN ULONG NumberMasks,
00048 OUT PCM_RESOURCE_LIST *Resource,
00049 OUT ULONG *Length
00050 );
00051
00052
#ifdef ALLOC_PRAGMA
00053
#pragma alloc_text(INIT, EisaBuildEisaDeviceNode)
00054
#pragma alloc_text(INIT, EisaGetEisaDevicesResources)
00055
#pragma alloc_text(INIT, EisaBuildSlotsResources)
00056
#endif
00057
00058
NTSTATUS
00059 EisaBuildEisaDeviceNode (
00060 VOID
00061 )
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 {
00080
NTSTATUS status;
00081 ULONG disposition, tmpValue;
00082 WCHAR buffer[
BUFFER_LENGTH];
00083
00084 UNICODE_STRING unicodeString;
00085 HANDLE rootHandle, deviceHandle, instanceHandle, logConfHandle;
00086
00087 PCM_RESOURCE_LIST resourceList;
00088 ULONG resourceLength;
00089
00090 status =
EisaGetEisaDevicesResources(&resourceList, &resourceLength);
00091
if (!
NT_SUCCESS(status) || resourceList ==
NULL) {
00092
return STATUS_UNSUCCESSFUL;
00093 }
00094
00095
RtlInitUnicodeString(&unicodeString,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\Root");
00096 status =
IopOpenRegistryKeyEx( &rootHandle,
00097
NULL,
00098 &unicodeString,
00099 KEY_ALL_ACCESS
00100 );
00101
00102
if (!
NT_SUCCESS(status)) {
00103
if (resourceList) {
00104
ExFreePool (resourceList);
00105 }
00106
return status;
00107 }
00108
00109
RtlInitUnicodeString(&unicodeString,
EISA_DEVICE_NODE_NAME);
00110 status =
IopCreateRegistryKeyEx( &deviceHandle,
00111 rootHandle,
00112 &unicodeString,
00113 KEY_ALL_ACCESS,
00114 REG_OPTION_NON_VOLATILE,
00115
NULL
00116 );
00117
00118 ZwClose(rootHandle);
00119
if (!
NT_SUCCESS(status)) {
00120
if (resourceList) {
00121
ExFreePool (resourceList);
00122 }
00123
return status;
00124 }
00125
00126
RtlInitUnicodeString( &unicodeString,
L"0000" );
00127 status =
IopCreateRegistryKeyEx( &instanceHandle,
00128 deviceHandle,
00129 &unicodeString,
00130 KEY_ALL_ACCESS,
00131 REG_OPTION_NON_VOLATILE,
00132 &disposition );
00133 ZwClose(deviceHandle);
00134
if (
NT_SUCCESS(status)) {
00135
if (disposition == REG_CREATED_NEW_KEY) {
00136
00137
RtlInitUnicodeString( &unicodeString,
L"DeviceDesc" );
00138 swprintf(buffer,
L"%s",
L"Device to report Eisa Slot Resources");
00139
00140 ZwSetValueKey(instanceHandle,
00141 &unicodeString,
00142 0,
00143 REG_SZ,
00144 buffer,
00145 (wcslen(buffer) + 1) *
sizeof(WCHAR)
00146 );
00147
00148
RtlInitUnicodeString( &unicodeString,
L"HardwareID" );
00149 RtlZeroMemory(buffer,
BUFFER_LENGTH *
sizeof(WCHAR));
00150 swprintf(buffer,
L"%s",
L"*Eisa_Resource_Device");
00151
00152 ZwSetValueKey(instanceHandle,
00153 &unicodeString,
00154 0,
00155 REG_MULTI_SZ,
00156 buffer,
00157 (wcslen(buffer) + 2) *
sizeof(WCHAR)
00158 );
00159
00160 PiWstrToUnicodeString(&unicodeString, REGSTR_VALUE_CONFIG_FLAGS);
00161 tmpValue = 0;
00162 ZwSetValueKey(instanceHandle,
00163 &unicodeString,
00164
TITLE_INDEX_VALUE,
00165 REG_DWORD,
00166 &tmpValue,
00167
sizeof(tmpValue)
00168 );
00169
00170 }
00171
00172
RtlInitUnicodeString( &unicodeString, REGSTR_KEY_LOGCONF );
00173 status =
IopCreateRegistryKeyEx( &logConfHandle,
00174 instanceHandle,
00175 &unicodeString,
00176 KEY_ALL_ACCESS,
00177 REG_OPTION_NON_VOLATILE,
00178
NULL
00179 );
00180 ZwClose(instanceHandle);
00181
if (
NT_SUCCESS(status)) {
00182
RtlInitUnicodeString( &unicodeString, REGSTR_VAL_BOOTCONFIG );
00183
00184 status = ZwSetValueKey(logConfHandle,
00185 &unicodeString,
00186 0,
00187 REG_RESOURCE_LIST,
00188 resourceList,
00189 resourceLength
00190 );
00191 ZwClose(logConfHandle);
00192 }
00193 }
00194
if (resourceList) {
00195
ExFreePool (resourceList);
00196 }
00197
return status;
00198 }
00199
00200
NTSTATUS
00201 EisaGetEisaDevicesResources (
00202 OUT PCM_RESOURCE_LIST *ResourceList,
00203 OUT PULONG ResourceLength
00204 )
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 {
00223
NTSTATUS status = STATUS_SUCCESS;
00224 PCM_RESOURCE_LIST resources =
NULL;
00225 HANDLE handle;
00226 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
00227 UNICODE_STRING unicodeString;
00228 ULONG slotMasks = 0, numberMasks = 0, i;
00229
00230 *ResourceList =
NULL;
00231 *ResourceLength = 0;
00232
00233
00234
00235
00236
00237
00238
RtlInitUnicodeString(&unicodeString,
L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\EisaAdapter");
00239 status =
IopOpenRegistryKeyEx( &handle,
00240
NULL,
00241 &unicodeString,
00242 KEY_READ
00243 );
00244
if (
NT_SUCCESS(status)) {
00245 status =
IopGetRegistryValue(handle,
00246
L"Configuration Data",
00247 &keyValueInformation
00248 );
00249
if (
NT_SUCCESS(status)) {
00250 PCM_FULL_RESOURCE_DESCRIPTOR resourceDescriptor;
00251 PCM_PARTIAL_RESOURCE_DESCRIPTOR partialResourceDescriptor;
00252
00253 resourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)
00254 ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset);
00255
00256
if ((keyValueInformation->DataLength >=
sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) &&
00257 (resourceDescriptor->PartialResourceList.Count > 0) ) {
00258 LONG eisaInfoLength;
00259 PCM_EISA_SLOT_INFORMATION eisaInfo;
00260
00261 partialResourceDescriptor = resourceDescriptor->PartialResourceList.PartialDescriptors;
00262
if (partialResourceDescriptor->Type == CmResourceTypeDeviceSpecific) {
00263 eisaInfo = (PCM_EISA_SLOT_INFORMATION)
00264 ((PUCHAR)partialResourceDescriptor +
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
00265 eisaInfoLength = (LONG)partialResourceDescriptor->u.DeviceSpecificData.DataSize;
00266
00267
00268
00269
00270
00271
for (i = 0; i < 0x10 && eisaInfoLength > 0; i++) {
00272
if (eisaInfo->ReturnCode == EISA_INVALID_SLOT) {
00273
break;
00274 }
00275
if (eisaInfo->ReturnCode != EISA_EMPTY_SLOT && (i != 0)) {
00276 slotMasks |= (1 << i);
00277 numberMasks++;
00278 }
00279
if (eisaInfo->ReturnCode == EISA_EMPTY_SLOT) {
00280 eisaInfoLength -=
sizeof(CM_EISA_SLOT_INFORMATION);
00281 eisaInfo++;
00282 }
else {
00283 eisaInfoLength -=
sizeof(CM_EISA_SLOT_INFORMATION) + eisaInfo->NumberFunctions *
sizeof(CM_EISA_FUNCTION_INFORMATION);
00284 eisaInfo = (PCM_EISA_SLOT_INFORMATION)
00285 ((PUCHAR)eisaInfo + eisaInfo->NumberFunctions *
sizeof(CM_EISA_FUNCTION_INFORMATION) +
00286
sizeof(CM_EISA_SLOT_INFORMATION));
00287 }
00288 }
00289
00290
if (slotMasks) {
00291 status =
EisaBuildSlotsResources(slotMasks, numberMasks, ResourceList, ResourceLength);
00292 }
00293 }
00294
00295 }
00296
ExFreePool(keyValueInformation);
00297 }
00298 ZwClose(handle);
00299 }
00300
return status;
00301 }
00302
00303
NTSTATUS
00304 EisaBuildSlotsResources (
00305 IN ULONG SlotMasks,
00306 IN ULONG NumberMasks,
00307 OUT PCM_RESOURCE_LIST *Resources,
00308 OUT ULONG *Length
00309 )
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 {
00329 PCM_RESOURCE_LIST resources =
NULL;
00330 PCM_PARTIAL_RESOURCE_DESCRIPTOR partialDesc;
00331 ULONG slot;
00332
00333 *Length =
sizeof(CM_RESOURCE_LIST) +
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (NumberMasks - 1);
00334 resources =
ExAllocatePool(
PagedPool, *Length);
00335
if (resources) {
00336 resources->Count = 1;
00337 resources->List[0].InterfaceType = Eisa;
00338 resources->List[0].BusNumber = 0;
00339 resources->List[0].PartialResourceList.Version = 0;
00340 resources->List[0].PartialResourceList.Revision = 0;
00341 resources->List[0].PartialResourceList.Count = NumberMasks;
00342 partialDesc = resources->List[0].PartialResourceList.PartialDescriptors;
00343 slot = 0;
00344
while (SlotMasks) {
00345 SlotMasks >>= 1;
00346 slot++;
00347
if (SlotMasks & 1) {
00348 partialDesc->Type = CmResourceTypePort;
00349 partialDesc->ShareDisposition = CmResourceShareDeviceExclusive;
00350 partialDesc->Flags = CM_RESOURCE_PORT_16_BIT_DECODE + CM_RESOURCE_PORT_IO;
00351 partialDesc->u.Port.Start.LowPart = slot << 12;
00352 partialDesc->u.Port.Start.HighPart = 0;
00353 partialDesc->u.Port.Length = 0x1000;
00354 partialDesc++;
00355 }
00356 }
00357 *Resources = resources;
00358
return STATUS_SUCCESS;
00359 }
else {
00360
return STATUS_NO_MEMORY;
00361 }
00362 }