[UDFS] Import a UDF File System Driver created by Alexander Telyatnikov (Alter) and...
[reactos.git] / reactos / drivers / filesystems / udfs / udfinit.cpp
1 ////////////////////////////////////////////////////////////////////
2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3 // All rights reserved
4 ////////////////////////////////////////////////////////////////////
5 /*************************************************************************
6 *
7 * File: UDFinit.cpp
8 *
9 * Module: UDF File System Driver (Kernel mode execution only)
10 *
11 * Description:
12 * This file contains the initialization code for the kernel mode
13 * UDF FSD module. The DriverEntry() routine is called by the I/O
14 * sub-system to initialize the FSD.
15 *
16 *************************************************************************/
17
18 #include "udffs.h"
19
20 // define the file specific bug-check id
21 #define UDF_BUG_CHECK_ID UDF_FILE_INIT
22
23 // global variables are declared here
24 UDFData UDFGlobalData;
25
26 #ifdef EVALUATION_TIME_LIMIT
27
28 ULONG PresentDateMask = 0;
29 BOOLEAN TrialEndOnStart = FALSE;
30
31 #define UDF_MD5Init UDF_MD5Init2
32 #define UDF_MD5Update UDF_MD5Update2
33 #define UDF_MD5Pad UDF_MD5Pad2
34 #define UDF_MD5Final UDF_MD5Final2
35 #define UDF_MD5End UDF_MD5End2
36 #define UDF_MD5Transform UDF_MD5Transform2
37 #define UDF_Encode UDF_Encode2
38 #define UDF_Decode UDF_Decode2
39 #define PADDING PADDING2
40
41 #define ROTATE_LEFT ROTATE_LEFT2
42 #define FF FF2
43 #define GG GG2
44 #define HH HH2
45 #define II II2
46
47 #define UDF_MD5Transform_dwords UDF_MD5Transform_dwords2
48 #define UDF_MD5Transform_idx UDF_MD5Transform_idx2
49 #define UDF_MD5Transform_Sxx UDF_MD5Transform_Sxx2
50 #define UDF_MD5Rotate UDF_MD5Rotate2
51
52 #include "..\Include\md5.h"
53 #include "..\Include\md5c.c"
54
55 #define UDF_FibonachiNum UDF_FibonachiNum2
56 #define XPEHb XPEHb2
57 #define UDF_build_long_key UDF_build_long_key2
58 #define UDF_build_hash_by_key UDF_build_hash_by_key2
59
60 #include "..\Include\key_lib.h"
61 #include "..\Include\key_lib.cpp"
62
63 extern ULONG UDFNumberOfKeys;
64 extern PCHAR pUDFLongKey;
65 extern PUDF_KEY_LIST pUDFKeyList;
66 extern PUCHAR pRegKeyName0;
67
68 #include "..\Include\protect.h"
69 #define INCLUDE_XOR_DECL_ONLY
70 #include "..\Include\protect.h"
71 #undef INCLUDE_XOR_DECL_ONLY
72
73 #endif //EVALUATION_TIME_LIMIT
74
75 #define KD_PREFIX
76
77 struct UDF_MEDIA_CLASS_NAMES UDFMediaClassName[] = {
78 {MediaUnknown, REG_DEFAULT_UNKNOWN},
79 {MediaHdd , REG_DEFAULT_HDD},
80 {MediaCdr , REG_DEFAULT_CDR},
81 {MediaCdrw , REG_DEFAULT_CDRW},
82 {MediaCdrom , REG_DEFAULT_CDROM},
83 {MediaZip , REG_DEFAULT_ZIP},
84 {MediaFloppy , REG_DEFAULT_FLOPPY},
85 {MediaDvdr , REG_DEFAULT_DVDR},
86 {MediaDvdrw , REG_DEFAULT_DVDRW}
87 };
88 /*
89 ULONG MajorVersion = 0;
90 ULONG MinorVersion = 0;
91 ULONG BuildNumber = 0;
92 */
93 ULONG FsRegistered = FALSE;
94
95 WORK_QUEUE_ITEM RemountWorkQueueItem;
96
97 //ptrFsRtlNotifyVolumeEvent FsRtlNotifyVolumeEvent = NULL;
98
99 HANDLE FsNotification_ThreadId = (HANDLE)(-1);
100
101 NTSTATUS
102 UDFCreateFsDeviceObject(
103 PCWSTR FsDeviceName,
104 PDRIVER_OBJECT DriverObject,
105 DEVICE_TYPE DeviceType,
106 PDEVICE_OBJECT *DeviceObject);
107
108 NTSTATUS
109 UDFDismountDevice(
110 PUNICODE_STRING unicodeCdRomDeviceName);
111
112 VOID
113 UDFRemountAll(
114 IN PVOID Context);
115
116 /*************************************************************************
117 *
118 * Function: DriverEntry()
119 *
120 * Description:
121 * This routine is the standard entry point for all kernel mode drivers.
122 * The routine is invoked at IRQL PASSIVE_LEVEL in the context of a
123 * system worker thread.
124 * All FSD specific data structures etc. are initialized here.
125 *
126 * Expected Interrupt Level (for execution) :
127 *
128 * IRQL_PASSIVE_LEVEL
129 *
130 * Return Value: STATUS_SUCCESS/Error (will cause driver to be unloaded).
131 *
132 *************************************************************************/
133 NTSTATUS
134 NTAPI
135 DriverEntry(
136 PDRIVER_OBJECT DriverObject, // created by the I/O sub-system
137 PUNICODE_STRING RegistryPath // path to the registry key
138 )
139 {
140 NTSTATUS RC = STATUS_SUCCESS;
141 UNICODE_STRING DriverDeviceName;
142 UNICODE_STRING unicodeDeviceName;
143 // BOOLEAN RegisteredShutdown = FALSE;
144 BOOLEAN InternalMMInitialized = FALSE;
145 // BOOLEAN DLDetectInitialized = FALSE;
146 // ULONG CdRomNumber;
147 // CCHAR deviceNameBuffer[MAXIMUM_FILENAME_LENGTH];
148 // ANSI_STRING deviceName;
149 // UNICODE_STRING unicodeCdRomDeviceName;
150 PUDFFS_DEV_EXTENSION FSDevExt;
151 HKEY hUdfRootKey;
152 #ifdef EVALUATION_TIME_LIMIT
153 WCHAR RegPath[128];
154 WCHAR RegKeyName[64];
155 CHAR LicenseKey[16+1];
156 ULONG iVer;
157
158 ULONG i, j;
159 int checksum[4] = {0,0,0,0};
160 #else
161 LARGE_INTEGER delay;
162 #endif //EVALUATION_TIME_LIMIT
163
164 // KdPrint(("UDF: Entered " VER_STR_PRODUCT_NAME " UDF DriverEntry \n"));
165 // KdPrint((KD_PREFIX "Build " VER_STR_PRODUCT "\n"));
166
167 #ifdef EVALUATION_TIME_LIMIT
168 BrutePoint();
169 #endif //EVALUATION_TIME_LIMIT
170
171 _SEH2_TRY {
172 _SEH2_TRY {
173
174 #ifdef EVALUATION_TIME_LIMIT
175 LARGE_INTEGER cTime;
176 #endif //EVALUATION_TIME_LIMIT
177
178 /*
179 CrNtInit(DriverObject, RegistryPath);
180
181 //PsGetVersion(&MajorVersion, &MinorVersion, &BuildNumber, NULL);
182 KdPrint(("UDF: OS Version Major: %x, Minor: %x, Build number: %d\n",
183 MajorVersion, MinorVersion, BuildNumber));
184 */
185 #ifdef __REACTOS__
186 KdPrint(("UDF Init: OS should be ReactOS\n"));
187 #endif
188
189 // initialize the global data structure
190 RtlZeroMemory(&UDFGlobalData, sizeof(UDFGlobalData));
191
192 // initialize some required fields
193 UDFGlobalData.NodeIdentifier.NodeType = UDF_NODE_TYPE_GLOBAL_DATA;
194 UDFGlobalData.NodeIdentifier.NodeSize = sizeof(UDFGlobalData);
195
196 #ifdef EVALUATION_TIME_LIMIT
197
198 KeQuerySystemTime((PLARGE_INTEGER)&cTime);
199
200 {
201 uint64 t, t2;
202 t = cTime.QuadPart / 100;
203 t /= 60;
204 t /= 200*120*24;
205 t /= 250;
206 t2 = (int32)t;
207 KdPrint((KD_PREFIX "t2 = %x\n", t2));
208 if(t2-TIME_JAN_1_2003 > UDF_MAX_DATE ||
209 t2-TIME_JAN_1_2003 < UDF_MIN_DATE) {
210 KdPrint((KD_PREFIX "Ssytem time is out of range: %x <= %x <= %x\n",
211 UDF_MIN_DATE, (uint32)t2-TIME_JAN_1_2003, UDF_MAX_DATE));
212 UDFGlobalData.UDFFlags |= UDF_DATA_FLAGS_UNREGISTERED;
213 }
214 }
215
216 if(UDFGetTrialEnd(&iVer)) {
217 TrialEndOnStart = TRUE;
218 KdPrint((KD_PREFIX "Eval time expired some time ago\n"));
219 UDFGlobalData.UDFFlags = (UDFGlobalData.UDFFlags & ~UDF_DATA_FLAGS_UNREGISTERED) + UDF_DATA_FLAGS_UNREGISTERED;
220 }
221 cTime.QuadPart /= (10*1000*1000);
222 cTime.QuadPart /= (60*60*24);
223
224 KdPrint((KD_PREFIX "cTime = %x, jTime = %x\n", cTime.LowPart, TIME_JAN_1_2003));
225 if(cTime.QuadPart < TIME_JAN_1_2003) {
226 KdPrint((KD_PREFIX "System time %x < TIME_JAN_1_2003\n", cTime.LowPart));
227 UDFGlobalData.UDFFlags |= UDF_DATA_FLAGS_UNREGISTERED;
228 }
229 cTime.LowPart -= TIME_JAN_1_2003;
230 KdPrint(("cTime = %x\n", cTime.LowPart));
231
232 if(!UDFGetInstallVersion((PULONG)&iVer) ||
233 !UDFGetInstallTime((PULONG)&cTime.HighPart)) {
234 KdPrint((KD_PREFIX "UDFGetInstallTime() or UDFGetInstallVersion() failed\n"));
235 UDFGlobalData.UDFFlags |= UDF_DATA_FLAGS_UNREGISTERED;
236 } else {
237 KdPrint((KD_PREFIX "cTime = %x, iTime = %x\n", cTime.LowPart, cTime.HighPart));
238 if(iVer > UDF_CURRENT_BUILD) {
239 KdPrint(("Init: Detected newer build (0)\n"));
240 UDFGlobalData.UDFFlags |= UDF_DATA_FLAGS_UNREGISTERED;
241 }
242 if((ULONG)cTime.LowPart < (ULONG)cTime.HighPart) {
243 KdPrint(("Eval time expired: current (%x) < install (%x)\n",
244 cTime.LowPart, cTime.HighPart));
245 UDFGlobalData.UDFFlags |= UDF_DATA_FLAGS_UNREGISTERED;
246 }
247 if((ULONG)cTime.LowPart > (ULONG)cTime.HighPart + EVALUATION_TERM) {
248 KdPrint(("Eval time expired above EVALUATION_TERM\n"));
249 UDFGlobalData.UDFFlags |= UDF_DATA_FLAGS_UNREGISTERED;
250 }
251 if((cTime.HighPart >> 16) & 0x8000) {
252 KdPrint(("Eval time expired (negative install time)\n"));
253 UDFGlobalData.UDFFlags |= UDF_DATA_FLAGS_UNREGISTERED;
254 }
255 }
256 if(UDFGlobalData.UDFFlags & UDF_DATA_FLAGS_UNREGISTERED) {
257 WCHAR s[16];
258 ULONG type, sz;
259 ULONG d;
260 PVOID pdata;
261
262 KdPrint(("Init: unregistered (3). Write BIAKAs to Registry\n"));
263 UDFGlobalData.UDFFlags |= UDF_DATA_FLAGS_UNREGISTERED;
264
265 // End of trial
266 d = 1 ^ XOR_VAR(TrialEnd, 0);
267 swprintf(s, L"0x%8.8x\0", d);
268 GET_TRIAL_REG_KEY_NAME(RegPath, 0);
269 GET_TRIAL_REG_VAL_NAME(RegKeyName, 0);
270 type = GET_XXX_REG_VAL_TYPE(TRIAL, 0) ? REG_SZ : REG_DWORD;
271 pdata = GET_XXX_REG_VAL_TYPE(TRIAL, 0) ? (PVOID)s : (PVOID)&d;
272 sz = GET_XXX_REG_VAL_TYPE(TRIAL, 0) ? (10+1+1)*sizeof(WCHAR) : sizeof(d);
273 KdPrint(("%ws\n %ws\n", RegPath, RegKeyName));
274 RC = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
275 RegPath, RegKeyName,
276 type, pdata, sz );
277 KdPrint(("status %#x\n", RC));
278 d = 1 ^ XOR_VAR(TrialEnd, 1);
279 swprintf(s, L"0x%8.8x\0", d);
280 GET_TRIAL_REG_KEY_NAME(RegPath, 1);
281 GET_TRIAL_REG_VAL_NAME(RegKeyName, 1);
282 type = GET_XXX_REG_VAL_TYPE(TRIAL, 1) ? REG_SZ : REG_DWORD;
283 pdata = GET_XXX_REG_VAL_TYPE(TRIAL, 1) ? (PVOID)s : (PVOID)&d;
284 sz = GET_XXX_REG_VAL_TYPE(TRIAL, 1) ? (10+1+1)*sizeof(WCHAR) : sizeof(d);
285 KdPrint(("%ws\n %ws\n", RegPath, RegKeyName));
286 RC = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
287 RegPath, RegKeyName,
288 type, pdata, sz );
289 KdPrint(("status %#x\n", RC));
290 // Install Date
291 if(!TrialEndOnStart) {
292 d = UDFGlobalData.iTime ^ XOR_VAR(Date, 0);
293 swprintf(s, L"0x%8.8x\0", d);
294 GET_DATE_REG_KEY_NAME(RegPath, 0);
295 GET_DATE_REG_VAL_NAME(RegKeyName, 0);
296 type = GET_XXX_REG_VAL_TYPE(DATE, 0) ? REG_SZ : REG_DWORD;
297 pdata = GET_XXX_REG_VAL_TYPE(DATE, 0) ? (PVOID)s : (PVOID)&d;
298 sz = GET_XXX_REG_VAL_TYPE(DATE, 0) ? (10+1+1)*sizeof(WCHAR) : sizeof(d);
299 if(!(PresentDateMask & (1 << 0))) {
300 KdPrint(("%ws\n %ws\n", RegPath, RegKeyName));
301 RC = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
302 RegPath, RegKeyName,
303 type, pdata, sz );
304 KdPrint(("status %#x\n", RC));
305 }
306 d = UDFGlobalData.iTime ^ XOR_VAR(Date, 1);
307 swprintf(s, L"0x%8.8x\0", d);
308 GET_DATE_REG_KEY_NAME(RegPath, 1);
309 GET_DATE_REG_VAL_NAME(RegKeyName, 1);
310 type = GET_XXX_REG_VAL_TYPE(DATE, 1) ? REG_SZ : REG_DWORD;
311 pdata = GET_XXX_REG_VAL_TYPE(DATE, 1) ? (PVOID)s : (PVOID)&d;
312 sz = GET_XXX_REG_VAL_TYPE(DATE, 1) ? (10+1+1)*sizeof(WCHAR) : sizeof(d);
313 if(!(PresentDateMask & (1 << 1))) {
314 KdPrint(("%ws\n %ws\n", RegPath, RegKeyName));
315 RC = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
316 RegPath, RegKeyName,
317 type, pdata, sz );
318 KdPrint(("status %#x\n", RC));
319 }
320 }
321 // Highest version
322 d = UDFGlobalData.iVer ^ XOR_VAR(Version, 0);
323 swprintf(s, L"0x%8.8x\0", d);
324 GET_VERSION_REG_KEY_NAME(RegPath, 0);
325 GET_VERSION_REG_VAL_NAME(RegKeyName, 0);
326 type = GET_XXX_REG_VAL_TYPE(VERSION, 0) ? REG_SZ : REG_DWORD;
327 pdata = GET_XXX_REG_VAL_TYPE(VERSION, 0) ? (PVOID)s : (PVOID)&d;
328 sz = GET_XXX_REG_VAL_TYPE(VERSION, 0) ? (10+1+1)*sizeof(WCHAR) : sizeof(d);
329 KdPrint(("%ws\n %ws\n", RegPath, RegKeyName));
330 RC = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
331 RegPath, RegKeyName,
332 type, pdata, sz );
333 KdPrint(("status %#x\n", RC));
334 d = UDFGlobalData.iVer ^ XOR_VAR(Version, 1);
335 swprintf(s, L"0x%8.8x\0", d);
336 GET_VERSION_REG_KEY_NAME(RegPath, 1);
337 GET_VERSION_REG_VAL_NAME(RegKeyName, 1);
338 type = GET_XXX_REG_VAL_TYPE(VERSION, 1) ? REG_SZ : REG_DWORD;
339 pdata = GET_XXX_REG_VAL_TYPE(VERSION, 1) ? (PVOID)s : (PVOID)&d;
340 sz = GET_XXX_REG_VAL_TYPE(VERSION, 1) ? (10+1+1)*sizeof(WCHAR) : sizeof(d);
341 KdPrint(("%ws\n %ws\n", RegPath, RegKeyName));
342 RC = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
343 RegPath, RegKeyName,
344 type, pdata, sz );
345 KdPrint(("status %#x\n", RC));
346 }
347 #endif //EVALUATION_TIME_LIMIT
348
349 // initialize the global data resource and remember the fact that
350 // the resource has been initialized
351 RC = UDFInitializeResourceLite(&(UDFGlobalData.GlobalDataResource));
352 ASSERT(NT_SUCCESS(RC));
353 UDFSetFlag(UDFGlobalData.UDFFlags, UDF_DATA_FLAGS_RESOURCE_INITIALIZED);
354
355 RC = UDFInitializeResourceLite(&(UDFGlobalData.DelayedCloseResource));
356 ASSERT(NT_SUCCESS(RC));
357 // UDFSetFlag(UDFGlobalData.UDFFlags, UDF_DATA_FLAGS_RESOURCE_INITIALIZED);
358
359 // keep a ptr to the driver object sent to us by the I/O Mgr
360 UDFGlobalData.DriverObject = DriverObject;
361
362 //SeEnableAccessToExports();
363
364 // initialize the mounted logical volume list head
365 InitializeListHead(&(UDFGlobalData.VCBQueue));
366
367 KdPrint(("UDF: Init memory manager\n"));
368 // Initialize internal memory management
369 if(!MyAllocInit()) {
370 try_return(RC = STATUS_INSUFFICIENT_RESOURCES);
371 }
372 InternalMMInitialized = TRUE;
373
374 #ifdef USE_DLD
375 // Initialize Deadlock Detector
376 DLDInit(1280);
377 DLDetectInitialized = TRUE;
378 #endif
379 // before we proceed with any more initialization, read in
380 // user supplied configurable values ...
381
382 // Save RegistryPath
383 RtlCopyMemory(&(UDFGlobalData.SavedRegPath), RegistryPath, sizeof(UNICODE_STRING));
384
385 UDFGlobalData.SavedRegPath.Buffer = (PWSTR)MyAllocatePool__(NonPagedPool, RegistryPath->Length + 2);
386 if(!UDFGlobalData.SavedRegPath.Buffer) try_return (RC = STATUS_INSUFFICIENT_RESOURCES);
387 RtlCopyMemory(UDFGlobalData.SavedRegPath.Buffer, RegistryPath->Buffer, RegistryPath->Length + 2);
388
389 RegTGetKeyHandle(NULL, UDFGlobalData.SavedRegPath.Buffer, &hUdfRootKey);
390
391 UDFGlobalData.UnicodeStrRoot.Buffer = L"\\"; //(PWCHAR)&(UDFGlobalData.UnicodeStrRootBuffer);
392 UDFGlobalData.UnicodeStrRoot.Length = sizeof(WCHAR);
393 UDFGlobalData.UnicodeStrRoot.MaximumLength = 2*sizeof(WCHAR);
394
395 UDFGlobalData.UnicodeStrSDir.Buffer = L":";
396 UDFGlobalData.UnicodeStrSDir.Length = sizeof(WCHAR);
397 UDFGlobalData.UnicodeStrSDir.MaximumLength = 2*sizeof(WCHAR);
398
399 UDFGlobalData.AclName.Buffer = UDF_SN_NT_ACL;
400 UDFGlobalData.AclName.Length =
401 (UDFGlobalData.AclName.MaximumLength = sizeof(UDF_SN_NT_ACL)) - sizeof(WCHAR);
402
403 KdPrint(("UDF: Init delayed close queues\n"));
404 #ifdef UDF_DELAYED_CLOSE
405 InitializeListHead( &UDFGlobalData.DelayedCloseQueue );
406 InitializeListHead( &UDFGlobalData.DirDelayedCloseQueue );
407
408 ExInitializeWorkItem( &UDFGlobalData.CloseItem,
409 (PWORKER_THREAD_ROUTINE) UDFDelayedClose,
410 NULL );
411
412 UDFGlobalData.DelayedCloseCount = 0;
413 UDFGlobalData.DirDelayedCloseCount = 0;
414 #endif //UDF_DELAYED_CLOSE
415
416 // we should have the registry data (if any), allocate zone memory ...
417 // This is an example of when FSD implementations __try to pre-allocate
418 // some fixed amount of memory to avoid internal fragmentation and/or waiting
419 // later during run-time ...
420
421 UDFGlobalData.DefaultZoneSizeInNumStructs=10;
422
423 KdPrint(("UDF: Init zones\n"));
424 if (!NT_SUCCESS(RC = UDFInitializeZones()))
425 try_return(RC);
426
427 KdPrint(("UDF: Init pointers\n"));
428 // initialize the IRP major function table, and the fast I/O table
429 UDFInitializeFunctionPointers(DriverObject);
430
431 UDFGlobalData.CPU_Count = KeNumberProcessors;
432 #ifdef EVALUATION_TIME_LIMIT
433 UDFGlobalData.Saved_j = 4;
434 #endif //EVALUATION_TIME_LIMIT
435
436 // create a device object representing the driver itself
437 // so that requests can be targeted to the driver ...
438 // e.g. for a disk-based FSD, "mount" requests will be sent to
439 // this device object by the I/O Manager.\
440 // For a redirector/server, you may have applications
441 // send "special" IOCTL's using this device object ...
442
443 RtlInitUnicodeString(&DriverDeviceName, UDF_FS_NAME);
444
445 KdPrint(("UDF: Create Driver dev obj\n"));
446 if (!NT_SUCCESS(RC = IoCreateDevice(
447 DriverObject, // our driver object
448 sizeof(UDFFS_DEV_EXTENSION), // don't need an extension for this object
449 &DriverDeviceName, // name - can be used to "open" the driver
450 // see the book for alternate choices
451 FILE_DEVICE_CD_ROM_FILE_SYSTEM,
452 0, // no special characteristics
453 // do not want this as an exclusive device, though you might
454 FALSE,
455 &(UDFGlobalData.UDFDeviceObject)))) {
456 // failed to create a device object, leave ...
457 try_return(RC);
458 }
459
460 FSDevExt = (PUDFFS_DEV_EXTENSION)((UDFGlobalData.UDFDeviceObject)->DeviceExtension);
461 // Zero it out (typically this has already been done by the I/O
462 // Manager but it does not hurt to do it again)!
463 RtlZeroMemory(FSDevExt, sizeof(UDFFS_DEV_EXTENSION));
464
465 // Initialize the signature fields
466 FSDevExt->NodeIdentifier.NodeType = UDF_NODE_TYPE_UDFFS_DRVOBJ;
467 FSDevExt->NodeIdentifier.NodeSize = sizeof(UDFFS_DEV_EXTENSION);
468
469 RtlInitUnicodeString(&unicodeDeviceName, UDF_DOS_FS_NAME);
470 IoCreateSymbolicLink(&unicodeDeviceName, &DriverDeviceName);
471
472 KdPrint(("UDF: Create CD dev obj\n"));
473 if (!NT_SUCCESS(RC = UDFCreateFsDeviceObject(UDF_FS_NAME_CD,
474 DriverObject,
475 FILE_DEVICE_CD_ROM_FILE_SYSTEM,
476 &(UDFGlobalData.UDFDeviceObject_CD)))) {
477 // failed to create a device object, leave ...
478 try_return(RC);
479 }
480 #ifdef UDF_HDD_SUPPORT
481 KdPrint(("UDF: Create HDD dev obj\n"));
482 if (!NT_SUCCESS(RC = UDFCreateFsDeviceObject(UDF_FS_NAME_HDD,
483 DriverObject,
484 FILE_DEVICE_DISK_FILE_SYSTEM,
485 &(UDFGlobalData.UDFDeviceObject_HDD)))) {
486 // failed to create a device object, leave ...
487 try_return(RC);
488 }
489 #endif //UDF_HDD_SUPPORT
490
491 /* RtlInitUnicodeString(&DriverDeviceName, UDF_FS_NAME_OTHER);
492
493 if (!NT_SUCCESS(RC = IoCreateDevice(
494 DriverObject, // our driver object
495 0, // don't need an extension for this object
496 &DriverDeviceName, // name - can be used to "open" the driver
497 // see the book for alternate choices
498 FILE_DEVICE_FILE_SYSTEM,
499 0, // no special characteristics
500 // do not want this as an exclusive device, though you might
501 FALSE,
502 &(UDFGlobalData.UDFDeviceObject_OTHER)))) {
503 // failed to create a device object, leave ...
504 try_return(RC);
505 }
506 // register the driver with the I/O Manager, pretend as if this is
507 // a physical disk based FSD (or in order words, this FSD manages
508 // logical volumes residing on physical disk drives)
509 IoRegisterFileSystem(UDFGlobalData.UDFDeviceObject_OTHER);
510
511 RtlInitUnicodeString(&DriverDeviceName, UDF_FS_NAME_TAPE);
512
513 if (!NT_SUCCESS(RC = IoCreateDevice(
514 DriverObject, // our driver object
515 0, // don't need an extension for this object
516 &DriverDeviceName, // name - can be used to "open" the driver
517 // see the book for alternate choices
518 FILE_DEVICE_TAPE_FILE_SYSTEM,
519 0, // no special characteristics
520 // do not want this as an exclusive device, though you might
521 FALSE,
522 &(UDFGlobalData.UDFDeviceObject_TAPE)))) {
523 // failed to create a device object, leave ...
524 try_return(RC);
525 }
526 // register the driver with the I/O Manager, pretend as if this is
527 // a physical disk based FSD (or in order words, this FSD manages
528 // logical volumes residing on physical disk drives)
529 IoRegisterFileSystem(UDFGlobalData.UDFDeviceObject_TAPE);
530 */
531
532 if (UDFGlobalData.UDFDeviceObject_CD) {
533 KdPrint(("UDFCreateFsDeviceObject: IoRegisterFileSystem() for CD\n"));
534 IoRegisterFileSystem(UDFGlobalData.UDFDeviceObject_CD);
535 }
536 #ifdef UDF_HDD_SUPPORT
537 if (UDFGlobalData.UDFDeviceObject_HDD) {
538 KdPrint(("UDFCreateFsDeviceObject: IoRegisterFileSystem() for HDD\n"));
539 IoRegisterFileSystem(UDFGlobalData.UDFDeviceObject_HDD);
540 }
541 #endif // UDF_HDD_SUPPORT
542 FsRegistered = TRUE;
543
544 KdPrint(("UDF: IoRegisterFsRegistrationChange()\n"));
545 IoRegisterFsRegistrationChange( DriverObject, (PDRIVER_FS_NOTIFICATION)UDFFsNotification );
546
547 // delay.QuadPart = -10000000;
548 // KeDelayExecutionThread(KernelMode, FALSE, &delay); //10 microseconds
549
550 #ifdef EVALUATION_TIME_LIMIT
551 // Build Registry Value name for License Key
552 for(i=0; i<UDFNumberOfKeys; i++) {
553 for(j=0; j<4; j++) {
554 checksum[j] += pUDFKeyList[i].d[j];
555 }
556 }
557
558 // Read Key
559 for(i=0; i<sizeof(UDF_LICENSE_KEY_USER)-1; i++) {
560 RegKeyName[i] = pRegKeyName0[(i*sizeof(UDF_LICENSE_KEY_USER))] ^ (UCHAR)(checksum[i%4] ^ (checksum[i%4] >> 16));
561 }
562 RegKeyName[i] = 0;
563
564 // RtlZeroMemory(UDFGlobalData.LicenseKeyW, sizeof(UDFGlobalData.LicenseKeyW));
565 RegTGetStringValue(hUdfRootKey, NULL,
566 RegKeyName, UDFGlobalData.LicenseKeyW, (16+1)*sizeof(WCHAR));
567 // UDFGlobalData.UDFFlags |= UDF_DATA_FLAGS_UNREGISTERED;
568 // }
569 RegTCloseKeyHandle(hUdfRootKey);
570
571 UDFGlobalData.LicenseKeyW[16] = 0;
572 // convert WCHAR Key to CHAR key
573 for(i=0; i<16; i++) {
574 LicenseKey[i] = (UCHAR)(UDFGlobalData.LicenseKeyW[i]);
575 }
576
577 // build hash
578 UDF_build_hash_by_key(pUDFLongKey, UDF_LONG_KEY_SIZE, (PCHAR)&(UDFGlobalData.CurrentKeyHash), LicenseKey);
579 // check if it is correct
580 for(i=0; i<UDFNumberOfKeys; i++) {
581 for(j=0; j<4; j++) {
582 if(pUDFKeyList[i].d[j] ^ UDFGlobalData.CurrentKeyHash.d[j]) {
583 break;
584 }
585 }
586 if(j==4)
587 break;
588 }
589 if((UDFGlobalData.Saved_j = j) == 4) {
590 UDFGlobalData.UDFFlags &= ~UDF_DATA_FLAGS_UNREGISTERED;
591 } else {
592 if(!(UDFGlobalData.UDFFlags & UDF_DATA_FLAGS_UNREGISTERED)) {
593 UDFGlobalData.Saved_j = 4;
594 }
595 }
596 #else //EVALUATION_TIME_LIMIT
597 delay.QuadPart = -10000000; // 1 sec
598 KeDelayExecutionThread(KernelMode, FALSE, &delay);
599 #endif //EVALUATION_TIME_LIMIT
600
601 #if 0
602 if(!WinVer_IsNT) {
603 /*ExInitializeWorkItem(&RemountWorkQueueItem, UDFRemountAll, NULL);
604 KdPrint(("UDFDriverEntry: create remount thread\n"));
605 ExQueueWorkItem(&RemountWorkQueueItem, DelayedWorkQueue);*/
606
607 for(CdRomNumber = 0;true;CdRomNumber++) {
608 sprintf(deviceNameBuffer, "\\Device\\CdRom%d", CdRomNumber);
609 KdPrint(( "UDF: DriverEntry : dismount %s\n", deviceNameBuffer));
610 RtlInitString(&deviceName, deviceNameBuffer);
611 RC = RtlAnsiStringToUnicodeString(&unicodeCdRomDeviceName, &deviceName, TRUE);
612
613 if (!NT_SUCCESS(RC)) {
614 RtlFreeUnicodeString(&unicodeCdRomDeviceName);
615 break;
616 }
617
618 RC = UDFDismountDevice(&unicodeCdRomDeviceName);
619 RtlFreeUnicodeString(&unicodeCdRomDeviceName);
620
621 if (!NT_SUCCESS(RC)) break;
622
623 }
624
625 PVOID ModuleBase = NULL;
626
627 // get NTOSKRNL.EXE exports
628 ModuleBase = CrNtGetModuleBase("NTOSKRNL.EXE");
629 if(ModuleBase) {
630 FsRtlNotifyVolumeEvent = (ptrFsRtlNotifyVolumeEvent)CrNtGetProcAddress(ModuleBase, "FsRtlNotifyVolumeEvent");
631 }
632
633 }
634 #endif
635 RC = STATUS_SUCCESS;
636
637 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
638 // we encountered an exception somewhere, eat it up
639 KdPrint(("UDF: exception\n"));
640 RC = _SEH2_GetExceptionCode();
641 } _SEH2_END;
642
643 InternalMMInitialized = FALSE;
644
645 try_exit: NOTHING;
646 } _SEH2_FINALLY {
647 // start unwinding if we were unsuccessful
648 if (!NT_SUCCESS(RC)) {
649 KdPrint(("UDF: failed with status %x\n", RC));
650 // Now, delete any device objects, etc. we may have created
651 /* if (UDFGlobalData.UDFDeviceObject) {
652 IoDeleteDevice(UDFGlobalData.UDFDeviceObject);
653 UDFGlobalData.UDFDeviceObject = NULL;
654 }*/
655 #ifdef USE_DLD
656 if (DLDetectInitialized) DLDFree();
657 #endif
658 if (InternalMMInitialized) {
659 MyAllocRelease();
660 }
661 if (UDFGlobalData.UDFDeviceObject_CD) {
662 IoDeleteDevice(UDFGlobalData.UDFDeviceObject_CD);
663 UDFGlobalData.UDFDeviceObject_CD = NULL;
664 }
665 #ifdef UDF_HDD_SUPPORT
666
667 if (UDFGlobalData.UDFDeviceObject_HDD) {
668 IoDeleteDevice(UDFGlobalData.UDFDeviceObject_HDD);
669 UDFGlobalData.UDFDeviceObject_HDD = NULL;
670 }
671 #endif // UDF_HDD_SUPPORT
672
673 /*
674 if (UDFGlobalData.UDFDeviceObject_OTHER) {
675 IoDeleteDevice(UDFGlobalData.UDFDeviceObject_CD);
676 UDFGlobalData.UDFDeviceObject_CD = NULL;
677 }
678
679 if (UDFGlobalData.UDFDeviceObject_TAPE) {
680 IoDeleteDevice(UDFGlobalData.UDFDeviceObject_CD);
681 UDFGlobalData.UDFDeviceObject_CD = NULL;
682 }
683 */
684 // free up any memory we might have reserved for zones/lookaside
685 // lists
686 if (UDFGlobalData.UDFFlags & UDF_DATA_FLAGS_ZONES_INITIALIZED) {
687 UDFDestroyZones();
688 }
689
690 // delete the resource we may have initialized
691 if (UDFGlobalData.UDFFlags & UDF_DATA_FLAGS_RESOURCE_INITIALIZED) {
692 // un-initialize this resource
693 UDFDeleteResource(&(UDFGlobalData.GlobalDataResource));
694 UDFClearFlag(UDFGlobalData.UDFFlags, UDF_DATA_FLAGS_RESOURCE_INITIALIZED);
695 }
696 // } else {
697 }
698 } _SEH2_END;
699
700 return(RC);
701 } // end DriverEntry()
702
703
704
705 /*************************************************************************
706 *
707 * Function: UDFInitializeFunctionPointers()
708 *
709 * Description:
710 * Initialize the IRP... function pointer array in the driver object
711 * structure. Also initialize the fast-io function ptr array ...
712 *
713 * Expected Interrupt Level (for execution) :
714 *
715 * IRQL_PASSIVE_LEVEL
716 *
717 * Return Value: None
718 *
719 *************************************************************************/
720 VOID
721 NTAPI
722 UDFInitializeFunctionPointers(
723 PDRIVER_OBJECT DriverObject // created by the I/O sub-system
724 )
725 {
726 PFAST_IO_DISPATCH PtrFastIoDispatch = NULL;
727
728 // initialize the function pointers for the IRP major
729 // functions that this FSD is prepared to handle ...
730 // NT Version 4.0 has 28 possible functions that a
731 // kernel mode driver can handle.
732 // NT Version 3.51 and before has only 22 such functions,
733 // of which 18 are typically interesting to most FSD's.
734
735 // The only interesting new functions that a FSD might
736 // want to respond to beginning with Version 4.0 are the
737 // IRP_MJ_QUERY_QUOTA and the IRP_MJ_SET_QUOTA requests.
738
739 // The code below does not handle quota manipulation, neither
740 // does the NT Version 4.0 operating system (or I/O Manager).
741 // However, you should be on the lookout for any such new
742 // functionality that the FSD might have to implement in
743 // the near future.
744
745 DriverObject->MajorFunction[IRP_MJ_CREATE] = UDFCreate;
746 DriverObject->MajorFunction[IRP_MJ_CLOSE] = UDFClose;
747 DriverObject->MajorFunction[IRP_MJ_READ] = UDFRead;
748 #ifndef UDF_READ_ONLY_BUILD
749 DriverObject->MajorFunction[IRP_MJ_WRITE] = UDFWrite;
750 #endif //UDF_READ_ONLY_BUILD
751
752 DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = UDFFileInfo;
753 #ifndef UDF_READ_ONLY_BUILD
754 DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = UDFFileInfo;
755 #endif //UDF_READ_ONLY_BUILD
756
757 #ifndef UDF_READ_ONLY_BUILD
758 DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = UDFFlush;
759 #endif //UDF_READ_ONLY_BUILD
760 // To implement support for querying and modifying volume attributes
761 // (volume information query/set operations), enable initialization
762 // of the following two function pointers and then implement the supporting
763 // functions.
764 DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = UDFQueryVolInfo;
765 #ifndef UDF_READ_ONLY_BUILD
766 #ifndef DEMO
767 DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = UDFSetVolInfo;
768 #endif //DEMO
769 #endif //UDF_READ_ONLY_BUILD
770 DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = UDFDirControl;
771 // To implement support for file system IOCTL calls, enable initialization
772 // of the following function pointer and implement appropriate support.
773 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = UDFFSControl;
774 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = UDFDeviceControl;
775 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = UDFShutdown;
776 // For byte-range lock support, enable initialization of the following
777 // function pointer and implement appropriate support.
778 DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = UDFLockControl;
779 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = UDFCleanup;
780 #ifdef UDF_HANDLE_EAS
781 DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = UDFQuerySetEA;
782 #ifndef UDF_READ_ONLY_BUILD
783 DriverObject->MajorFunction[IRP_MJ_SET_EA] = UDFQuerySetEA;
784 #endif //UDF_READ_ONLY_BUILD
785 #endif //UDF_HANDLE_EAS
786 // If the FSD supports security attributes, we should provide appropriate
787 // dispatch entry points and initialize the function pointers as given below.
788
789 #ifdef UDF_ENABLE_SECURITY
790 DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = UDFGetSecurity;
791 #ifndef UDF_READ_ONLY_BUILD
792 #ifndef DEMO
793 DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = UDFSetSecurity;
794 #endif //DEMO
795 #endif //UDF_READ_ONLY_BUILD
796 #endif //UDF_ENABLE_SECURITY
797
798 // if(MajorVersion >= 0x05) {
799 // w2k and higher
800 // DriverObject->MajorFunction[IRP_MJ_PNP] = UDFPnp;
801 // }
802
803 // Now, it is time to initialize the fast-io stuff ...
804 PtrFastIoDispatch = DriverObject->FastIoDispatch = &(UDFGlobalData.UDFFastIoDispatch);
805
806 // initialize the global fast-io structure
807 // NOTE: The fast-io structure has undergone a substantial revision
808 // in Windows NT Version 4.0. The structure has been extensively expanded.
809 // Therefore, if the driver needs to work on both V3.51 and V4.0+,
810 // we will have to be able to distinguish between the two versions at compile time.
811
812 RtlZeroMemory(PtrFastIoDispatch, sizeof(FAST_IO_DISPATCH));
813
814 PtrFastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
815 PtrFastIoDispatch->FastIoCheckIfPossible = UDFFastIoCheckIfPossible;
816 PtrFastIoDispatch->FastIoRead = FsRtlCopyRead;
817 #ifndef UDF_READ_ONLY_BUILD
818 PtrFastIoDispatch->FastIoWrite = UDFFastIoCopyWrite /*FsRtlCopyWrite*/;
819 #endif //UDF_READ_ONLY_BUILD
820 PtrFastIoDispatch->FastIoQueryBasicInfo = UDFFastIoQueryBasicInfo;
821 PtrFastIoDispatch->FastIoQueryStandardInfo = UDFFastIoQueryStdInfo;
822 PtrFastIoDispatch->FastIoLock = UDFFastLock; // Lock
823 PtrFastIoDispatch->FastIoUnlockSingle = UDFFastUnlockSingle; // UnlockSingle
824 PtrFastIoDispatch->FastIoUnlockAll = UDFFastUnlockAll; // UnlockAll
825 PtrFastIoDispatch->FastIoUnlockAllByKey = (unsigned char (__stdcall *)(struct _FILE_OBJECT *,
826 PVOID ,unsigned long,struct _IO_STATUS_BLOCK *,struct _DEVICE_OBJECT *))UDFFastUnlockAllByKey; // UnlockAllByKey
827
828 PtrFastIoDispatch->AcquireFileForNtCreateSection = UDFFastIoAcqCreateSec;
829 PtrFastIoDispatch->ReleaseFileForNtCreateSection = UDFFastIoRelCreateSec;
830
831 // PtrFastIoDispatch->FastIoDeviceControl = UDFFastIoDeviceControl;
832
833 // the remaining are only valid under NT Version 4.0 and later
834 #if(_WIN32_WINNT >= 0x0400)
835
836 PtrFastIoDispatch->FastIoQueryNetworkOpenInfo = UDFFastIoQueryNetInfo;
837
838 PtrFastIoDispatch->AcquireForModWrite = UDFFastIoAcqModWrite;
839 PtrFastIoDispatch->ReleaseForModWrite = UDFFastIoRelModWrite;
840 PtrFastIoDispatch->AcquireForCcFlush = UDFFastIoAcqCcFlush;
841 PtrFastIoDispatch->ReleaseForCcFlush = UDFFastIoRelCcFlush;
842
843 /* // MDL functionality
844
845 PtrFastIoDispatch->MdlRead = UDFFastIoMdlRead;
846 PtrFastIoDispatch->MdlReadComplete = UDFFastIoMdlReadComplete;
847 PtrFastIoDispatch->PrepareMdlWrite = UDFFastIoPrepareMdlWrite;
848 PtrFastIoDispatch->MdlWriteComplete = UDFFastIoMdlWriteComplete;*/
849
850 // this FSD does not support compressed read/write functionality,
851 // NTFS does, and if we design a FSD that can provide such functionality,
852 // we should consider initializing the fast io entry points for reading
853 // and/or writing compressed data ...
854 #endif // (_WIN32_WINNT >= 0x0400)
855
856 // last but not least, initialize the Cache Manager callback functions
857 // which are used in CcInitializeCacheMap()
858
859 UDFGlobalData.CacheMgrCallBacks.AcquireForLazyWrite = UDFAcqLazyWrite;
860 UDFGlobalData.CacheMgrCallBacks.ReleaseFromLazyWrite = UDFRelLazyWrite;
861 UDFGlobalData.CacheMgrCallBacks.AcquireForReadAhead = UDFAcqReadAhead;
862 UDFGlobalData.CacheMgrCallBacks.ReleaseFromReadAhead = UDFRelReadAhead;
863
864 DriverObject->DriverUnload = UDFDriverUnload;
865
866 return;
867 } // end UDFInitializeFunctionPointers()
868
869 NTSTATUS
870 UDFCreateFsDeviceObject(
871 PCWSTR FsDeviceName,
872 PDRIVER_OBJECT DriverObject,
873 DEVICE_TYPE DeviceType,
874 PDEVICE_OBJECT *DeviceObject
875 )
876 {
877 NTSTATUS RC = STATUS_SUCCESS;
878 UNICODE_STRING DriverDeviceName;
879 PUDFFS_DEV_EXTENSION FSDevExt;
880 RtlInitUnicodeString(&DriverDeviceName, FsDeviceName);
881 *DeviceObject = NULL;
882
883 KdPrint(("UDFCreateFsDeviceObject: create dev\n"));
884
885 if (!NT_SUCCESS(RC = IoCreateDevice(
886 DriverObject, // our driver object
887 sizeof(UDFFS_DEV_EXTENSION), // don't need an extension for this object
888 &DriverDeviceName, // name - can be used to "open" the driver
889 // see the book for alternate choices
890 DeviceType,
891 0, // no special characteristics
892 // do not want this as an exclusive device, though you might
893 FALSE,
894 DeviceObject))) {
895 // failed to create a device object, leave ...
896 return(RC);
897 }
898 FSDevExt = (PUDFFS_DEV_EXTENSION)((*DeviceObject)->DeviceExtension);
899 // Zero it out (typically this has already been done by the I/O
900 // Manager but it does not hurt to do it again)!
901 RtlZeroMemory(FSDevExt, sizeof(UDFFS_DEV_EXTENSION));
902
903 // Initialize the signature fields
904 FSDevExt->NodeIdentifier.NodeType = UDF_NODE_TYPE_UDFFS_DEVOBJ;
905 FSDevExt->NodeIdentifier.NodeSize = sizeof(UDFFS_DEV_EXTENSION);
906 // register the driver with the I/O Manager, pretend as if this is
907 // a physical disk based FSD (or in order words, this FSD manages
908 // logical volumes residing on physical disk drives)
909 /* KdPrint(("UDFCreateFsDeviceObject: IoRegisterFileSystem()\n"));
910 IoRegisterFileSystem(*DeviceObject);*/
911 return(RC);
912 } // end UDFCreateFsDeviceObject()
913
914
915 NTSTATUS
916 UDFDismountDevice(
917 PUNICODE_STRING unicodeCdRomDeviceName
918 )
919 {
920 NTSTATUS RC;
921 IO_STATUS_BLOCK IoStatus;
922 HANDLE NtFileHandle = (HANDLE)-1;
923 OBJECT_ATTRIBUTES ObjectAttributes;
924 NOTIFY_MEDIA_CHANGE_USER_IN buffer = { 0 };
925 PFILE_FS_ATTRIBUTE_INFORMATION Buffer;
926
927 _SEH2_TRY {
928
929 Buffer = (PFILE_FS_ATTRIBUTE_INFORMATION)MyAllocatePool__(NonPagedPool,sizeof(FILE_FS_ATTRIBUTE_INFORMATION)+2*sizeof(UDF_FS_TITLE_DVDRAM));
930 if (!Buffer) try_return(RC = STATUS_INSUFFICIENT_RESOURCES);
931
932 InitializeObjectAttributes ( &ObjectAttributes,
933 unicodeCdRomDeviceName,
934 OBJ_CASE_INSENSITIVE,
935 NULL,
936 NULL );
937
938 KdPrint(("\n*** UDFDismountDevice: Create\n"));
939 RC = ZwCreateFile( &NtFileHandle,
940 GENERIC_READ,
941 &ObjectAttributes,
942 &IoStatus,
943 NULL,
944 FILE_ATTRIBUTE_NORMAL,
945 FILE_SHARE_READ,
946 FILE_OPEN,
947 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
948 NULL,
949 0 );
950
951
952 if (!NT_SUCCESS(RC)) try_return(RC);
953
954 KdPrint(("\n*** UDFDismountDevice: QueryVolInfo\n"));
955 RC = ZwQueryVolumeInformationFile( NtFileHandle,
956 &IoStatus,
957 Buffer,
958 sizeof(FILE_FS_ATTRIBUTE_INFORMATION)+2*sizeof(UDF_FS_TITLE_DVDRAM),
959 FileFsAttributeInformation);
960
961 #define UDF_CHECK_FS_NAME(name) \
962 (Buffer->FileSystemNameLength+sizeof(WCHAR) == sizeof(name) && \
963 DbgCompareMemory(&Buffer->FileSystemName[0],name , sizeof(name)) == sizeof(name))
964
965 if (NT_SUCCESS(RC) &&
966 (UDF_CHECK_FS_NAME(UDF_FS_TITLE_CDR) ||
967 UDF_CHECK_FS_NAME(UDF_FS_TITLE_CDRW) ||
968 UDF_CHECK_FS_NAME(UDF_FS_TITLE_DVDR) ||
969 UDF_CHECK_FS_NAME(UDF_FS_TITLE_DVDRW) ||
970 UDF_CHECK_FS_NAME(UDF_FS_TITLE_DVDpR) ||
971 UDF_CHECK_FS_NAME(UDF_FS_TITLE_DVDpRW) ||
972 UDF_CHECK_FS_NAME(UDF_FS_TITLE_DVDRAM) )) try_return(STATUS_SUCCESS);
973
974 KdPrint(("\n*** UDFDismountDevice: LockVolume\n"));
975 RC = ZwFsControlFile(NtFileHandle,
976 NULL,
977 NULL,
978 NULL,
979 &IoStatus,
980 FSCTL_LOCK_VOLUME,
981 NULL,
982 NULL,
983 NULL,
984 NULL);
985
986 if (!NT_SUCCESS(RC)) try_return(RC);
987
988 KdPrint(("\n*** UDFDismountDevice: DismountVolume\n"));
989 RC = ZwFsControlFile(NtFileHandle,
990 NULL,
991 NULL,
992 NULL,
993 &IoStatus,
994 FSCTL_DISMOUNT_VOLUME,
995 NULL,
996 NULL,
997 NULL,
998 NULL);
999
1000 if (!NT_SUCCESS(RC)) try_return(RC);
1001
1002 KdPrint(("\n*** UDFDismountDevice: NotifyMediaChange\n"));
1003 RC = ZwDeviceIoControlFile(NtFileHandle,
1004 NULL,
1005 NULL,
1006 NULL,
1007 &IoStatus,
1008 IOCTL_CDRW_NOTIFY_MEDIA_CHANGE,
1009 &buffer,
1010 sizeof(buffer),
1011 &buffer,
1012 sizeof(buffer));
1013
1014 if (!NT_SUCCESS(RC)) try_return(RC);
1015
1016
1017 KdPrint(("\n*** UDFDismountDevice: UnlockVolume\n"));
1018 RC = ZwFsControlFile(NtFileHandle,
1019 NULL,
1020 NULL,
1021 NULL,
1022 &IoStatus,
1023 FSCTL_UNLOCK_VOLUME,
1024 NULL,
1025 NULL,
1026 NULL,
1027 NULL);
1028
1029 KdPrint(("\n*** UDFDismountDevice: Close\n"));
1030 ZwClose( NtFileHandle );
1031
1032 NtFileHandle = (HANDLE)-1;
1033
1034 KdPrint(("\n*** UDFDismountDevice: Create 2\n"));
1035 RC = ZwCreateFile( &NtFileHandle,
1036 GENERIC_READ,
1037 &ObjectAttributes,
1038 &IoStatus,
1039 NULL,
1040 FILE_ATTRIBUTE_NORMAL,
1041 FILE_SHARE_READ,
1042 FILE_OPEN,
1043 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
1044 NULL,
1045 0 );
1046
1047 try_exit: NOTHING;
1048
1049 } _SEH2_FINALLY {
1050 if (Buffer) MyFreePool__(Buffer);
1051 if (NtFileHandle != (HANDLE)-1) ZwClose( NtFileHandle );
1052 } _SEH2_END;
1053
1054 KdPrint(("\n*** UDFDismountDevice: RC=%x\n",RC));
1055 return RC;
1056 }
1057
1058
1059 VOID
1060 NTAPI
1061 UDFFsNotification(
1062 IN PDEVICE_OBJECT DeviceObject,
1063 IN BOOLEAN FsActive
1064 )
1065
1066 /*
1067
1068 Routine Description:
1069
1070 This routine is invoked whenever a file system has either registered or
1071 unregistered itself as an active file system.
1072
1073 For the former case, this routine creates a device object and attaches it
1074 to the specified file system's device object. This allows this driver
1075 to filter all requests to that file system.
1076
1077 For the latter case, this file system's device object is located,
1078 detached, and deleted. This removes this file system as a filter for
1079 the specified file system.
1080
1081 Arguments:
1082
1083 DeviceObject - Pointer to the file system's device object.
1084
1085 FsActive - bolean indicating whether the file system has registered
1086 (TRUE) or unregistered (FALSE) itself as an active file system.
1087
1088 Return Value:
1089
1090 None.
1091
1092 */
1093
1094 {
1095 // Begin by determine whether or not the file system is a cdrom-based file
1096 // system. If not, then this driver is not concerned with it.
1097 if (!FsRegistered ||
1098 DeviceObject->DeviceType != FILE_DEVICE_CD_ROM_FILE_SYSTEM) {
1099 return;
1100 }
1101
1102 // Begin by determining whether this file system is registering or
1103 // unregistering as an active file system.
1104 if (FsActive
1105 && UDFGlobalData.UDFDeviceObject_CD != DeviceObject
1106 #ifdef UDF_HDD_SUPPORT
1107 && UDFGlobalData.UDFDeviceObject_HDD != DeviceObject
1108 #endif // UDF_HDD_SUPPORT
1109 ) {
1110 KdPrint(("\n*** UDFFSNotification \n\n"));
1111
1112 // Acquire GlobalDataResource
1113 UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
1114
1115 if(FsNotification_ThreadId != PsGetCurrentThreadId()) {
1116
1117 FsNotification_ThreadId = PsGetCurrentThreadId();
1118
1119 IoUnregisterFileSystem(UDFGlobalData.UDFDeviceObject_CD);
1120 IoRegisterFileSystem(UDFGlobalData.UDFDeviceObject_CD);
1121
1122 #ifdef UDF_HDD_SUPPORT
1123 IoUnregisterFileSystem(UDFGlobalData.UDFDeviceObject_HDD);
1124 IoRegisterFileSystem(UDFGlobalData.UDFDeviceObject_HDD);
1125 #endif // UDF_HDD_SUPPORT
1126
1127 FsNotification_ThreadId = (HANDLE)(-1);
1128
1129 } else {
1130 KdPrint(("\n*** recursive UDFFSNotification call,\n can't become top-level UDF FSD \n\n"));
1131 }
1132
1133 // Release the global resource.
1134 UDFReleaseResource( &(UDFGlobalData.GlobalDataResource) );
1135
1136
1137 }
1138 }
1139 /*VOID
1140 UDFRemountAll(
1141 IN PVOID Context
1142 )
1143 {
1144 NTSTATUS RC = STATUS_SUCCESS;
1145 ULONG CdRomNumber;
1146 CCHAR deviceNameBuffer[MAXIMUM_FILENAME_LENGTH];
1147 ANSI_STRING deviceName;
1148 UNICODE_STRING unicodeCdRomDeviceName;
1149 LARGE_INTEGER delay;
1150
1151 /* delay.QuadPart = -80*10000000;
1152 KeDelayExecutionThread(KernelMode, FALSE, &delay); //10 seconds*/
1153
1154 /* for(CdRomNumber = 0;true;CdRomNumber++) {
1155 sprintf(deviceNameBuffer, "\\Device\\CdRom%d", CdRomNumber);
1156 KdPrint(( "UDF: UDFRemountAll : dismount %s\n", deviceNameBuffer));
1157 RtlInitString(&deviceName, deviceNameBuffer);
1158 RC = RtlAnsiStringToUnicodeString(&unicodeCdRomDeviceName, &deviceName, TRUE);
1159
1160 if (!NT_SUCCESS(RC)) {
1161 RtlFreeUnicodeString(&unicodeCdRomDeviceName);
1162 break;
1163 }
1164
1165 RC = UDFDismountDevice(&unicodeCdRomDeviceName);
1166 RtlFreeUnicodeString(&unicodeCdRomDeviceName);
1167
1168 if (!NT_SUCCESS(RC)) break;
1169 }
1170 }*/
1171
1172
1173 #ifdef EVALUATION_TIME_LIMIT
1174
1175 BOOLEAN
1176 UDFGetInstallVersion(
1177 PULONG iVer
1178 )
1179 {
1180 WCHAR RegPath[128];
1181 WCHAR RegVal[64];
1182 WCHAR Str[32];
1183 ULONG i, j;
1184 ULONG a, v;
1185 ULONG type;
1186 ULONG sz;
1187
1188 KdPrint((KD_PREFIX "UDFGetInstallVersion:\n"));
1189
1190 (*iVer) = UDF_CURRENT_BUILD;
1191 for(j=0; j<UDF_INSTALL_INFO_LOCATIONS; j++) {
1192 RtlZeroMemory(Str, sizeof(Str));
1193 switch(j) {
1194 case 0: GET_VERSION_REG_KEY_NAME(RegPath, 0); break;
1195 case 1: GET_VERSION_REG_KEY_NAME(RegPath, 1); break;
1196 }
1197 v = 0;
1198 switch(j) {
1199 case 0: GET_VERSION_REG_VAL_NAME(RegVal, 0); break;
1200 case 1: GET_VERSION_REG_VAL_NAME(RegVal, 1); break;
1201 }
1202 type = 0;
1203 if(j) {
1204 type = GET_XXX_REG_VAL_TYPE(VERSION, 1);
1205 } else {
1206 type = GET_XXX_REG_VAL_TYPE(VERSION, 0);
1207 }
1208 if(!type &&
1209 RegTGetDwordValue(NULL, RegPath, RegVal, &v)) {
1210 // ok
1211 KdPrint((KD_PREFIX "val: %x\n", v));
1212 goto de_xor;
1213 } else
1214 if(type &&
1215 (sz = 30) &&
1216 RegTGetStringValue(NULL, RegPath, RegVal,
1217 &Str[0], sz) &&
1218 wcslen(Str) == 10)
1219 {
1220 for(i=2; i<10; i++) {
1221 if(Str[i] >= 'a' && Str[i] <= 'f') {
1222 a = 10 + Str[i] - 'a';
1223 } else {
1224 a = Str[i] - '0';
1225 }
1226 KdPrint((KD_PREFIX "val: %x\n", a));
1227 v *= 16;
1228 v += a;
1229 }
1230 de_xor:
1231 switch(j) {
1232 case 0: v ^= XOR_VAR(Version, 0); break;
1233 case 1: v ^= XOR_VAR(Version, 1); break;
1234 }
1235 if(v & 0x80000000)
1236 continue;
1237 if((*iVer) == -1 || (*iVer) < v) {
1238 (*iVer) = v;
1239 }
1240 UDFGlobalData.iVer = (*iVer);
1241 }
1242 }
1243 UDFGlobalData.iVer = (*iVer);
1244 /* if(UDFGlobalData.iVer == -1)
1245 return FALSE;*/
1246 KdPrint((KD_PREFIX "ret val: %x\n", *iVer));
1247 if((*iVer) > UDF_CURRENT_BUILD) {
1248 return FALSE;
1249 }
1250 return TRUE;
1251 } // end UDFGetInstallVersion()
1252
1253 BOOLEAN
1254 UDFGetInstallTime(
1255 PULONG iTime
1256 )
1257 {
1258 WCHAR RegPath[128];
1259 WCHAR RegVal[64];
1260 WCHAR Str[32];
1261 ULONG i, j;
1262 ULONG a, v;
1263 ULONG type;
1264 ULONG sz;
1265
1266 KdPrint((KD_PREFIX "UDFGetInstallTime:\n"));
1267
1268 (*iTime) = -1;
1269 for(j=0; j<UDF_INSTALL_INFO_LOCATIONS; j++) {
1270 RtlZeroMemory(Str, sizeof(Str));
1271 switch(j) {
1272 case 0: GET_DATE_REG_KEY_NAME(RegPath, 0); break;
1273 case 1: GET_DATE_REG_KEY_NAME(RegPath, 1); break;
1274 }
1275 v = 0;
1276 switch(j) {
1277 case 0: GET_DATE_REG_VAL_NAME(RegVal, 0); break;
1278 case 1: GET_DATE_REG_VAL_NAME(RegVal, 1); break;
1279 }
1280 type = 0;
1281 if(j) {
1282 type = GET_XXX_REG_VAL_TYPE(DATE, 1);
1283 } else {
1284 type = GET_XXX_REG_VAL_TYPE(DATE, 0);
1285 }
1286 if(!type &&
1287 RegTGetDwordValue(NULL, RegPath, RegVal, &v)) {
1288 // ok
1289 KdPrint((KD_PREFIX "val: %x\n", v));
1290 goto de_xor;
1291 } else
1292 if(type &&
1293 (sz = 30) &&
1294 RegTGetStringValue(NULL, RegPath, RegVal,
1295 &Str[0], sz) &&
1296 wcslen(Str) == 10)
1297 {
1298 for(i=2; i<10; i++) {
1299 if(Str[i] >= 'a' && Str[i] <= 'f') {
1300 a = 10 + Str[i] - 'a';
1301 } else {
1302 a = Str[i] - '0';
1303 }
1304 KdPrint((KD_PREFIX "val: %x\n", a));
1305 v *= 16;
1306 v += a;
1307 }
1308 de_xor:
1309 switch(j) {
1310 case 0: v ^= XOR_VAR(Date, 0); break;
1311 case 1: v ^= XOR_VAR(Date, 1); break;
1312 }
1313 PresentDateMask |= 0x00000001 << j;
1314 if(v & 0x80000000)
1315 continue;
1316 if((*iTime) == -1 || (*iTime) < v) {
1317 (*iTime) = v;
1318 }
1319 UDFGlobalData.iTime = (*iTime);
1320 }
1321 }
1322 UDFGlobalData.iTime = (*iTime);
1323 if(UDFGlobalData.iTime == -1) {
1324
1325 LARGE_INTEGER cTime;
1326 KeQuerySystemTime((PLARGE_INTEGER)&cTime);
1327
1328 cTime.QuadPart /= (10*1000*1000);
1329 cTime.QuadPart /= (60*60*24);
1330
1331 KdPrint((KD_PREFIX "cTime = %x, jTime = %x\n", cTime.LowPart, TIME_JAN_1_2003));
1332 if(cTime.QuadPart < TIME_JAN_1_2003) {
1333 KdPrint((KD_PREFIX "Eval time expired (1)\n"));
1334 UDFGlobalData.UDFFlags |= UDF_DATA_FLAGS_UNREGISTERED;
1335 }
1336 cTime.LowPart -= TIME_JAN_1_2003;
1337 KdPrint(("cTime = %x\n", cTime.LowPart));
1338
1339 UDFGlobalData.iTime = (*iTime) = cTime.LowPart;
1340 return FALSE;
1341 }
1342 UDFGlobalData.iTime = (*iTime);
1343 KdPrint((KD_PREFIX "ret val: %x\n", *iTime));
1344 return TRUE;
1345 } // end UDFGetInstallTime()
1346
1347 BOOLEAN
1348 UDFGetTrialEnd(
1349 PULONG iTrial
1350 )
1351 {
1352 WCHAR RegPath[128];
1353 WCHAR RegVal[64];
1354 WCHAR Str[32];
1355 ULONG i, j;
1356 ULONG a, v;
1357 ULONG type;
1358 ULONG sz;
1359
1360 KdPrint((KD_PREFIX "UDFGetTrialEnd:\n"));
1361
1362 (*iTrial) = 0;
1363 for(j=0; j<UDF_INSTALL_INFO_LOCATIONS; j++) {
1364 RtlZeroMemory(Str, sizeof(Str));
1365 switch(j) {
1366 case 0: GET_TRIAL_REG_KEY_NAME(RegPath, 0); break;
1367 case 1: GET_TRIAL_REG_KEY_NAME(RegPath, 1); break;
1368 }
1369 v = 0;
1370 switch(j) {
1371 case 0: GET_TRIAL_REG_VAL_NAME(RegVal, 0); break;
1372 case 1: GET_TRIAL_REG_VAL_NAME(RegVal, 1); break;
1373 }
1374 type = 0;
1375 if(j) {
1376 type = GET_XXX_REG_VAL_TYPE(TRIAL, 1);
1377 } else {
1378 type = GET_XXX_REG_VAL_TYPE(TRIAL, 0);
1379 }
1380 if(!type &&
1381 RegTGetDwordValue(NULL, RegPath, RegVal, &v)) {
1382 // ok
1383 KdPrint((KD_PREFIX "val: %x\n", v));
1384 goto de_xor;
1385 } else
1386 if(type &&
1387 (sz = 30) &&
1388 RegTGetStringValue(NULL, RegPath, RegVal,
1389 &Str[0], sz) &&
1390 wcslen(Str) == 10)
1391 {
1392 for(i=2; i<10; i++) {
1393 if(Str[i] >= 'a' && Str[i] <= 'f') {
1394 a = 10 + Str[i] - 'a';
1395 } else {
1396 a = Str[i] - '0';
1397 }
1398 KdPrint((KD_PREFIX "val: %x\n", a));
1399 v *= 16;
1400 v += a;
1401 }
1402 de_xor:
1403 switch(j) {
1404 case 0: v ^= XOR_VAR(TrialEnd, 0); break;
1405 case 1: v ^= XOR_VAR(TrialEnd, 1); break;
1406 }
1407 if((*iTrial) < v) {
1408 (*iTrial) = v;
1409 }
1410 if(UDFGlobalData.iTrial = (*iTrial)) {
1411 return TRUE;
1412 }
1413 }
1414 }
1415 return FALSE;
1416 } // end UDFGetTrialEnd()
1417
1418 #endif //EVALUATION_TRIAL_LIMIT
1419
1420
1421