[UDFS] Import a UDF File System Driver created by Alexander Telyatnikov (Alter) and...
authorAmine Khaldi <amine.khaldi@reactos.org>
Sat, 6 Jun 2015 12:52:13 +0000 (12:52 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sat, 6 Jun 2015 12:52:13 +0000 (12:52 +0000)
svn path=/trunk/; revision=68036

115 files changed:
reactos/drivers/filesystems/CMakeLists.txt
reactos/drivers/filesystems/udfs/CMakeLists.txt [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/CrossNt/CrNtDecl.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/CrossNt/CrNtStubs.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/CrossNt/CrossNt.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/CrossNt/ilock.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/CrossNt/misc.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/CrossNt/rwlock.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/Sys_spec_lib.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/Sys_spec_lib.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/check_env.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/common.rc [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/common_dwn.rc [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/env_spec_nt.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/env_spec_nt.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/env_spec_w32.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/env_spec_w32.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/format_common.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/format_common.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/getopt.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/getopt.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/key_lib.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/key_lib.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/keys.cpp.tpl [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/md5.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/md5c.c [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/mem_tools.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/mem_tools.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/misc_common.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/mountmgr.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/nt_native.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/ntddk_ex.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/ntddscsi.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/phys_lib.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/phys_lib.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/platform.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/product.tph [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/protect.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/protect_reg.tph [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/protect_user_mode.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/regtools.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/regtools.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/string_lib.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/tools.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/tools.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/udf_common.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/udf_lib_common.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/udf_reg.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/udferr_usr.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/udferr_usr.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/user_lib.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/user_lib.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/version.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/wcache_lib.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/wcache_lib.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/Include/zw_2_nt.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/cleanup.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/close.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/create.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/devcntrl.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/dircntrl.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/dldetect.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/dldetect.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/env_spec.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/env_spec.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/errmsg.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/fastio.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/fileinfo.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/filter.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/flush.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/fscntrl.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/lockctrl.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/mem.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/mem.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/misc.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/namesup.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/namesup.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/ntifs_ex.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/pnp.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/protos.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/read.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/secursup.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/shutdown.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/struct.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/sys_spec.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/sys_spec.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_dbg.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_dbg.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/alloc.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/build.mak [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/dirtree.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/ecma_167.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/extent.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/mount.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/osta_misc.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/phys_eject.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/physical.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/prec_hdr2.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/remap.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/udf.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/udf_info.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/udf_info.dep [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/udf_info.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/udf_info.mak [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udf_info/udf_rel.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udffs.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udffs.rc [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udfinit.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/udfpubl.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/unload.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/verfysup.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/volinfo.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/wcache.cpp [new file with mode: 0644]
reactos/drivers/filesystems/udfs/wcache.h [new file with mode: 0644]
reactos/drivers/filesystems/udfs/write.cpp [new file with mode: 0644]

index 1dd2bc7..a9ffab1 100644 (file)
@@ -8,3 +8,7 @@ add_subdirectory(msfs)
 add_subdirectory(mup)
 add_subdirectory(npfs)
 add_subdirectory(ntfs)
+if(MSVC)
+    # FIXME: Make sure this compiles with the *nix builder before enabling it
+    add_subdirectory(udfs)
+endif()
diff --git a/reactos/drivers/filesystems/udfs/CMakeLists.txt b/reactos/drivers/filesystems/udfs/CMakeLists.txt
new file mode 100644 (file)
index 0000000..db9ada3
--- /dev/null
@@ -0,0 +1,55 @@
+
+include_directories(include)
+
+set_cpp(WITH_RUNTIME)
+
+list(APPEND SOURCE
+    udf_info/alloc.cpp
+    udf_info/dirtree.cpp
+    udf_info/extent.cpp
+    udf_info/mount.cpp
+    udf_info/phys_eject.cpp
+    udf_info/physical.cpp
+    udf_info/remap.cpp
+    udf_info/udf_info.cpp
+    cleanup.cpp
+    close.cpp
+    create.cpp
+    devcntrl.cpp
+    dircntrl.cpp
+    env_spec.cpp
+    fastio.cpp
+    fileinfo.cpp
+    filter.cpp
+    flush.cpp
+    fscntrl.cpp
+    lockctrl.cpp
+    mem.cpp
+    misc.cpp
+    namesup.cpp
+    pnp.cpp
+    read.cpp
+    secursup.cpp
+    shutdown.cpp
+    sys_spec.cpp
+    udf_dbg.cpp
+    udfinit.cpp
+    unload.cpp
+    verfysup.cpp
+    volinfo.cpp
+    wcache.cpp
+    write.cpp)
+
+add_library(udfs SHARED ${SOURCE} udffs.rc)
+if(MSVC)
+    # FIXME: Make sure we marked all what needs to be marked with stdcall before removing this.
+    add_target_compile_flags(udfs "/Gz")
+else()
+    # FIXME: Tons of warnings.
+    replace_compile_flags("-Werror" " ")
+    add_target_compile_flags(udfs "-fpermissive")
+endif()
+set_module_type(udfs kernelmodedriver)
+target_link_libraries(udfs ${PSEH_LIB})
+add_importlibs(udfs ntoskrnl hal)
+add_cd_file(TARGET udfs DESTINATION reactos/system32/drivers NO_CAB FOR all)
diff --git a/reactos/drivers/filesystems/udfs/Include/CrossNt/CrNtDecl.h b/reactos/drivers/filesystems/udfs/Include/CrossNt/CrNtDecl.h
new file mode 100644 (file)
index 0000000..86f5d41
--- /dev/null
@@ -0,0 +1,58 @@
+
+#ifdef CROSSNT_DECL
+#undef CROSSNT_DECL
+#undef CROSSNT_DECL_EX
+#endif //CROSSNT_DECL
+
+/***************************/
+#ifdef CROSSNT_DECL_API
+
+#define CROSSNT_DECL(type, dspec, name, args, callargs) \
+typedef type (dspec *ptr##name) args;        \
+extern "C" ptr##name CrNt##name; \
+type dspec CrNt##name##_impl args;
+
+#define CROSSNT_DECL_EX(mod, type, dspec, name, args, callargs) \
+typedef type (dspec *ptr##name) args;        \
+extern "C" ptr##name CrNt##name; \
+type dspec CrNt##name##_impl args;
+
+#endif //CROSSNT_DECL_API
+
+/***************************/
+#ifdef CROSSNT_DECL_STUB
+
+#define CROSSNT_DECL(type, dspec, name, args, callargs) \
+extern "C" ptr##name CrNt##name = NULL;          \
+
+#define CROSSNT_DECL_EX(mod, type, dspec, name, args, callargs) \
+extern "C" ptr##name CrNt##name = NULL;          \
+
+#endif //CROSSNT_DECL_STUB
+
+/***************************/
+#ifdef CROSSNT_INIT_STUB
+
+#define CROSSNT_DECL(type, dspec, name, args, callargs) \
+    KdPrint(("Init " #name " cur %x\n", CrNt##name)); \
+    if(!CrNt##name) {                 \
+        CrNt##name = (ptr##name)CrNtGetProcAddress(g_hNtosKrnl, #name); \
+        KdPrint(("  GetProcAddr(NTOSKRNL.EXE," #name ") = %x\n", CrNt##name)); \
+        if(!CrNt##name) {             \
+            CrNt##name = CrNt##name##_impl; \
+        }                              \
+        KdPrint(("  final %\n", CrNt##name)); \
+    }
+
+#define CROSSNT_DECL_EX(mod, type, dspec, name, args, callargs) \
+    KdPrint(("Init " mod "," #name " cur %x\n", CrNt##name)); \
+    if(!CrNt##name) {                 \
+        CrNt##name = (ptr##name)CrNtGetProcAddress(CrNtGetModuleBase(mod), #name); \
+        KdPrint(("  GetProcAddr(" mod "," #name ") = %x\n", CrNt##name)); \
+        if(!CrNt##name) {             \
+            CrNt##name = CrNt##name##_impl; \
+        }                              \
+        KdPrint(("  final %x\n", CrNt##name)); \
+    }
+
+#endif //CROSSNT_INIT_STUB
diff --git a/reactos/drivers/filesystems/udfs/Include/CrossNt/CrNtStubs.h b/reactos/drivers/filesystems/udfs/Include/CrossNt/CrNtStubs.h
new file mode 100644 (file)
index 0000000..adb4860
--- /dev/null
@@ -0,0 +1,109 @@
+
+CROSSNT_DECL(
+HANDLE,__stdcall,
+PsGetCurrentProcessId,(),())
+
+CROSSNT_DECL(
+HANDLE,__stdcall,
+PsGetCurrentThreadId,(),())
+
+CROSSNT_DECL(
+BOOLEAN,
+__fastcall,
+KeTestSpinLock,(
+    IN PKSPIN_LOCK SpinLock
+    ),
+    (
+    SpinLock
+    ))
+
+CROSSNT_DECL(
+LONG,
+__fastcall,
+InterlockedIncrement,(
+    IN OUT PLONG Addend
+    ),
+    (
+    IN OUT PLONG Addend
+    ))
+
+CROSSNT_DECL(
+LONG,
+__fastcall,
+InterlockedDecrement,(
+    IN OUT PLONG Addend
+    ),
+    (
+    IN OUT PLONG Addend
+    ))
+
+CROSSNT_DECL(
+LONG,
+__fastcall,
+InterlockedExchangeAdd,(
+    IN OUT PLONG Addend,
+    IN LONG Increment
+    ),
+    (
+    IN OUT PLONG Addend,
+    IN LONG Increment
+    ))
+
+CROSSNT_DECL(
+PVOID,
+__fastcall,
+InterlockedCompareExchange,(
+    IN OUT PVOID *Destination,
+    IN PVOID ExChange,
+    IN PVOID Comperand
+    ),
+    (
+    IN OUT PVOID *Destination,
+    IN PVOID ExChange,
+    IN PVOID Comperand
+    ))
+
+CROSSNT_DECL_EX("HAL.DLL",
+KIRQL,__stdcall,
+KeRaiseIrqlToDpcLevel,(),())
+
+CROSSNT_DECL_EX("HAL.DLL",
+KIRQL,__stdcall,
+KeRaiseIrqlToSynchLevel,(),())
+
+CROSSNT_DECL_EX("NDIS.SYS",
+VOID,
+__stdcall,
+NdisInitializeReadWriteLock,(
+    IN PNDIS_RW_LOCK Lock
+    ),
+    (
+    Lock
+    ))
+
+CROSSNT_DECL_EX("NDIS.SYS",
+VOID,
+__stdcall,
+NdisAcquireReadWriteLock,(
+    IN PNDIS_RW_LOCK Lock,
+    IN BOOLEAN       fWrite,
+    IN PLOCK_STATE   LockState
+    ),
+    (
+    Lock,
+    fWrite,
+    LockState
+    ))
+
+CROSSNT_DECL_EX("NDIS.SYS",
+VOID,
+__stdcall,
+NdisReleaseReadWriteLock,(
+    IN PNDIS_RW_LOCK Lock,
+    IN PLOCK_STATE   LockState
+    ),
+    (
+    Lock,
+    LockState
+    ))
+
diff --git a/reactos/drivers/filesystems/udfs/Include/CrossNt/CrossNt.h b/reactos/drivers/filesystems/udfs/Include/CrossNt/CrossNt.h
new file mode 100644 (file)
index 0000000..5619834
--- /dev/null
@@ -0,0 +1,147 @@
+#ifndef __CROSS_VERSION_LIB_NT__H__
+#define __CROSS_VERSION_LIB_NT__H__
+
+extern "C" {
+
+#pragma pack(push, 8)
+
+#if !defined(NT_INCLUDED)
+#include <ntddk.h>                  // various NT definitions
+#endif 
+
+#include <stddef.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include "ntddk_ex.h"
+
+#include "rwlock.h"
+
+#ifdef CROSS_NT_INTERNAL
+#include "ilock.h"
+#endif //CROSS_NT_INTERNAL
+
+#include "misc.h"
+#include "tools.h"
+
+#pragma pack(pop)
+
+extern "C"
+NTSTATUS
+CrNtInit(
+    IN PDRIVER_OBJECT DriverObject,
+    IN PUNICODE_STRING RegistryPath
+    );
+
+extern "C"
+ULONG
+CrNtGetCPUGen();
+
+extern "C"
+PVOID
+CrNtGetModuleBase(
+    IN PCHAR  pModuleName
+    );
+
+extern "C"
+PVOID
+CrNtFindModuleBaseByPtr(
+    IN PVOID  ptrInSection,
+    IN PCHAR  ptrExportedName
+    );
+
+extern "C"
+PVOID
+CrNtGetProcAddress(
+    PVOID ModuleBase,
+    PCHAR pFunctionName
+    );
+
+typedef BOOLEAN (__stdcall *ptrCrNtPsGetVersion)(
+    PULONG MajorVersion OPTIONAL,
+    PULONG MinorVersion OPTIONAL,
+    PULONG BuildNumber OPTIONAL,
+    PUNICODE_STRING CSDVersion OPTIONAL
+    );
+
+extern "C"
+ptrCrNtPsGetVersion  CrNtPsGetVersion;
+
+typedef NTSTATUS (__stdcall *ptrCrNtNtQuerySystemInformation)(
+    IN SYSTEM_INFORMATION_CLASS SystemInfoClass,
+    OUT PVOID                   SystemInfoBuffer,
+    IN ULONG                    SystemInfoBufferSize,
+    OUT PULONG                  BytesReturned OPTIONAL
+    );
+
+extern "C"
+ptrCrNtNtQuerySystemInformation  CrNtNtQuerySystemInformation;
+
+extern "C"
+PVOID
+CrNtSkipImportStub(
+    PVOID p
+    );
+
+extern "C" {
+
+extern ULONG  MajorVersion;
+extern ULONG  MinorVersion;
+extern ULONG  BuildNumber;
+extern ULONG  SPVersion;
+
+extern HANDLE g_hNtosKrnl;
+extern HANDLE g_hHal;
+
+extern PCHAR  g_KeNumberProcessors;
+
+};
+
+#define WinVer_Is351   (MajorVersion==0x03)
+#define WinVer_IsNT    (MajorVersion==0x04)
+#define WinVer_Is2k    (MajorVersion==0x05 && MinorVersion==0x00)
+#define WinVer_IsXP    (MajorVersion==0x05 && MinorVersion==0x01)
+#define WinVer_IsXPp   (MajorVersion==0x05 && MinorVersion>=0x01)
+#define WinVer_IsdNET  (MajorVersion==0x05 && MinorVersion==0x02)
+#define WinVer_IsdNETp ((MajorVersion==0x05 && MinorVersion>=0x02) || (MajorVersion>0x05))
+#define WinVer_IsVista (MajorVersion==0x06 && MinorVersion==0x00)
+
+#define WinVer_Id()   ((MajorVersion << 8) | MinorVersion)
+
+#define WinVer_351    (0x0351)
+#define WinVer_NT     (0x0400)
+#define WinVer_ROS    (0x0401)
+#define WinVer_2k     (0x0500)
+#define WinVer_XP     (0x0501)
+#define WinVer_dNET   (0x0502)
+#define WinVer_Vista  (0x0600)
+
+#ifdef _DEBUG
+
+// NT3.51 doesn't export strlen() and strcmp()
+// The same time, Release build doesn't depend no these functions since they are inlined
+
+size_t __cdecl CrNtstrlen (
+        const char * str
+        );
+
+int __cdecl CrNtstrcmp (
+        const char * src,
+        const char * dst
+        );
+
+#define strlen CrNtstrlen
+#define strcmp CrNtstrcmp
+
+#endif //_DEBUG
+
+#define CROSSNT_DECL_API
+
+#include "CrNtDecl.h"
+#include "CrNtStubs.h"
+
+#undef CROSSNT_DECL_API
+
+}; // end extern "C"
+
+#endif //__CROSS_VERSION_LIB_NT__H__
\ No newline at end of file
diff --git a/reactos/drivers/filesystems/udfs/Include/CrossNt/ilock.h b/reactos/drivers/filesystems/udfs/Include/CrossNt/ilock.h
new file mode 100644 (file)
index 0000000..4c1a7c4
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef __CROSS_NT_INTERLOCKED__H__
+#define __CROSS_NT_INTERLOCKED__H__
+
+LONG
+__fastcall
+CrNtInterlockedIncrement_impl_i386_MP(
+    IN OUT PLONG Addend
+    );
+
+LONG
+__fastcall
+CrNtInterlockedIncrement_impl_i386_UP(
+    IN OUT PLONG Addend
+    );
+
+/********************************************************/
+
+LONG
+__fastcall
+CrNtInterlockedDecrement_impl_i386_MP(
+    IN OUT PLONG Addend
+    );
+
+LONG
+__fastcall
+CrNtInterlockedDecrement_impl_i386_UP(
+    IN OUT PLONG Addend
+    );
+
+/********************************************************/
+
+LONG
+__fastcall
+CrNtInterlockedExchangeAdd_impl_i386_MP(
+    IN OUT PLONG Addend,
+    IN LONG Increment
+    );
+
+LONG
+__fastcall
+CrNtInterlockedExchangeAdd_impl_i386_UP(
+    IN OUT PLONG Addend,
+    IN LONG Increment
+    );
+
+/********************************************************/
+
+PVOID
+__fastcall
+CrNtInterlockedCompareExchange_impl_i386_MP(
+    IN OUT PVOID *Destination,
+    IN PVOID ExChange,
+    IN PVOID Comperand
+    );
+
+PVOID
+__fastcall
+CrNtInterlockedCompareExchange_impl_i386_UP(
+    IN OUT PVOID *Destination,
+    IN PVOID ExChange,
+    IN PVOID Comperand
+    );
+
+#endif __CROSS_NT_INTERLOCKED__H__
diff --git a/reactos/drivers/filesystems/udfs/Include/CrossNt/misc.h b/reactos/drivers/filesystems/udfs/Include/CrossNt/misc.h
new file mode 100644 (file)
index 0000000..5b0ac6f
--- /dev/null
@@ -0,0 +1,148 @@
+#ifndef __CROSSNT_MISC__H__
+#define __CROSSNT_MISC__H__
+
+#ifdef _X86_
+
+typedef void
+(__fastcall *ptrMOV_DD_SWP)(
+    void* a, // ECX
+    void* b  // EDX
+    );
+extern "C" ptrMOV_DD_SWP _MOV_DD_SWP;
+
+extern "C"
+void
+__fastcall
+_MOV_DD_SWP_i486(
+    void* a, // ECX
+    void* b  // EDX
+    );
+
+extern "C"
+void
+__fastcall
+_MOV_DD_SWP_i386(
+    void* a, // ECX
+    void* b  // EDX
+    );
+#define MOV_DD_SWP(a,b) _MOV_DD_SWP(&(a),&(b))
+
+/********************/
+
+extern "C"
+void
+__fastcall
+_MOV_DW_SWP(
+    void* a, // ECX
+    void* b  // EDX
+    );
+
+#define MOV_DW_SWP(a,b) _MOV_DW_SWP(&(a),&(b))
+
+/********************/
+
+typedef void
+(__fastcall *ptrREVERSE_DD)(
+    void* a  // ECX
+    );
+extern "C" ptrREVERSE_DD _REVERSE_DD;
+
+void
+__fastcall
+_REVERSE_DD_i486(
+    void* a  // ECX
+    );
+
+void
+__fastcall
+_REVERSE_DD_i386(
+    void* a  // ECX
+    );
+#define REVERSE_DD(a) _REVERSE_DD(&(a))
+
+/********************/
+
+extern "C"
+void
+__fastcall
+_REVERSE_DW(
+    void* a  // ECX
+    );
+
+#define REVERSE_DW(a) _REVERSE_DW(&(a))
+
+/********************/
+
+extern "C"
+void
+__fastcall
+_MOV_DW2DD_SWP(
+    void* a, // ECX
+    void* b  // EDX
+    );
+
+#define MOV_DW2DD_SWP(a,b) _MOV_DW2DD_SWP(&(a),&(b))
+
+/********************/
+
+extern "C"
+void
+__fastcall
+_MOV_SWP_DW2DD(
+    void* a, // ECX
+    void* b  // EDX
+    );
+
+#define MOV_SWP_DW2DD(a,b) _MOV_SWP_DW2DD(&(a),&(b))
+
+/********************/
+
+extern "C"
+void
+__fastcall
+_MOV_MSF(
+    void* a, // ECX
+    void* b  // EDX
+    );
+#define MOV_MSF(a,b) _MOV_MSF(&(a),&(b))
+
+/********************/
+
+typedef void
+(__fastcall *ptrMOV_MSF_SWP)(
+    void* a, // ECX
+    void* b  // EDX
+    );
+extern "C" ptrMOV_MSF_SWP _MOV_MSF_SWP;
+
+extern "C"
+void
+__fastcall
+_MOV_MSF_SWP_i486(
+    void* a, // ECX
+    void* b  // EDX
+    );
+
+extern "C"
+void
+__fastcall
+_MOV_MSF_SWP_i386(
+    void* a, // ECX
+    void* b  // EDX
+    );
+#define MOV_MSF_SWP(a,b) _MOV_MSF_SWP(&(a),&(b))
+
+/********************/
+
+extern "C"
+void
+__fastcall
+_XCHG_DD(
+    void* a, // ECX
+    void* b  // EDX
+    );
+#define XCHG_DD(a,b) _XCHG_DD(&(a),&(b))
+
+#endif //_X86_
+
+#endif // __CROSSNT_MISC__H__
diff --git a/reactos/drivers/filesystems/udfs/Include/CrossNt/rwlock.h b/reactos/drivers/filesystems/udfs/Include/CrossNt/rwlock.h
new file mode 100644 (file)
index 0000000..3f0bf22
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef __CROSS_NT_RWLOCK__H__
+#define __CROSS_NT_RWLOCK__H__
+
+#ifndef        MAXIMUM_PROCESSORS
+#define        MAXIMUM_PROCESSORS      32
+#endif
+
+typedef union _NDIS_RW_LOCK_REFCOUNT {
+    unsigned int                 RefCount;
+    UCHAR                        cacheLine[16];    // One refCount per cache line
+} NDIS_RW_LOCK_REFCOUNT;
+
+typedef struct _NDIS_RW_LOCK {
+    union  {
+        struct {
+            KSPIN_LOCK           SpinLock;
+            PVOID                Context;
+        };
+        UCHAR                    Reserved[16];
+    };
+
+    NDIS_RW_LOCK_REFCOUNT        RefCount[MAXIMUM_PROCESSORS];
+} NDIS_RW_LOCK, *PNDIS_RW_LOCK;
+
+typedef struct _LOCK_STATE {
+    USHORT     LockState;
+    KIRQL      OldIrql;
+} LOCK_STATE, *PLOCK_STATE;
+
+#define RWLOCK_STATE_FREE             0
+#define RWLOCK_STATE_READ_ACQUIRED    1
+#define RWLOCK_STATE_WRITE_ACQUIRED   2
+#define RWLOCK_STATE_RECURSIVE        3
+#define RWLOCK_STATE_RELEASED         0xffff
+
+#define RWLOCK_FOR_WRITE              TRUE
+#define RWLOCK_FOR_READ               FALSE
+
+#endif /* __CROSS_NT_RWLOCK__H__ */
diff --git a/reactos/drivers/filesystems/udfs/Include/Sys_spec_lib.cpp b/reactos/drivers/filesystems/udfs/Include/Sys_spec_lib.cpp
new file mode 100644 (file)
index 0000000..ed91fb0
--- /dev/null
@@ -0,0 +1,1042 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+/*************************************************************************
+*
+* File: Sys_Spec.cpp
+*
+* Module: UDF File System Driver 
+* (both User and Kernel mode execution)
+*
+* Description:
+*   Contains system-secific code
+*
+*************************************************************************/
+
+
+/*
+    This routine converts UDF timestamp to NT time
+ */
+LONGLONG
+UDFTimeToNT(
+    IN PUDF_TIME_STAMP UdfTime
+    )
+{
+    LONGLONG NtTime;
+    TIME_FIELDS TimeFields;
+
+    TimeFields.Milliseconds = (USHORT)(UdfTime->centiseconds * 10 + UdfTime->hundredsOfMicroseconds / 100);
+    TimeFields.Second = (USHORT)(UdfTime->second);
+    TimeFields.Minute = (USHORT)(UdfTime->minute);
+    TimeFields.Hour = (USHORT)(UdfTime->hour);
+    TimeFields.Day = (USHORT)(UdfTime->day);
+    TimeFields.Month = (USHORT)(UdfTime->month);
+    TimeFields.Year = (USHORT)((UdfTime->year < 1601) ? 1601 : UdfTime->year);
+
+    if (!RtlTimeFieldsToTime(&TimeFields, (PLARGE_INTEGER)&NtTime)) {
+        NtTime = 0;
+    } else {
+        ExLocalTimeToSystemTime( (PLARGE_INTEGER)&NtTime, (PLARGE_INTEGER)&NtTime );
+    }
+
+    return NtTime;
+} // end UDFTimeToNT()
+
+
+/*
+    This routine converts NT time to UDF timestamp
+ */
+VOID
+UDFTimeToUDF(
+    IN LONGLONG NtTime,
+    OUT PUDF_TIME_STAMP UdfTime
+    )
+{
+    if(!NtTime) return;
+    LONGLONG LocalTime;
+
+    TIME_FIELDS TimeFields;
+
+    ExSystemTimeToLocalTime( (PLARGE_INTEGER)&NtTime, (PLARGE_INTEGER)&LocalTime );
+    RtlTimeToTimeFields( (PLARGE_INTEGER)&LocalTime, &TimeFields );
+
+    LocalTime /= 10; // microseconds
+    UdfTime->microseconds = (UCHAR)(NtTime % 100);
+    LocalTime /= 100; // hundreds of microseconds
+    UdfTime->hundredsOfMicroseconds = (UCHAR)(NtTime % 100);
+    LocalTime /= 100; // centiseconds
+    UdfTime->centiseconds = (UCHAR)(TimeFields.Milliseconds / 10);
+    UdfTime->second = (UCHAR)(TimeFields.Second);
+    UdfTime->minute = (UCHAR)(TimeFields.Minute);
+    UdfTime->hour = (UCHAR)(TimeFields.Hour);
+    UdfTime->day = (UCHAR)(TimeFields.Day);
+    UdfTime->month = (UCHAR)(TimeFields.Month);
+    UdfTime->year = (USHORT)(TimeFields.Year);
+    UdfTime->typeAndTimezone = (TIMESTAMP_TYPE_LOCAL << 14);
+} // end UDFTimeToUDF()
+
+/*
+ */
+ULONG
+UDFAttributesToNT(
+    IN PDIR_INDEX_ITEM FileDirNdx,
+    IN tag* FileEntry
+    )
+{
+    ASSERT(FileDirNdx);
+    if( (FileDirNdx->FI_Flags & UDF_FI_FLAG_SYS_ATTR) &&
+       !(FileDirNdx->FI_Flags & UDF_FI_FLAG_LINKED))
+        return FileDirNdx->SysAttr;
+
+    ULONG NTAttr = 0;
+    ULONG attr = 0; //permissions
+    USHORT Flags = 0;
+    USHORT Type = 0;
+    UCHAR FCharact = 0;
+
+    if(!FileEntry) {
+        if(!FileDirNdx->FileInfo)
+            return 0;
+        ValidateFileInfo(FileDirNdx->FileInfo);
+        FileEntry = FileDirNdx->FileInfo->Dloc->FileEntry;
+    }
+    if(FileEntry->tagIdent == TID_FILE_ENTRY) {
+        attr = ((PFILE_ENTRY)FileEntry)->permissions;
+        Flags = ((PFILE_ENTRY)FileEntry)->icbTag.flags;
+        Type = ((PFILE_ENTRY)FileEntry)->icbTag.fileType;
+        if(((PFILE_ENTRY)FileEntry)->fileLinkCount > 1)
+            FileDirNdx->FI_Flags |= UDF_FI_FLAG_LINKED;
+    } else {
+        attr = ((PEXTENDED_FILE_ENTRY)FileEntry)->permissions;
+        Flags = ((PEXTENDED_FILE_ENTRY)FileEntry)->icbTag.flags;
+        Type = ((PEXTENDED_FILE_ENTRY)FileEntry)->icbTag.fileType;
+        if(((PEXTENDED_FILE_ENTRY)FileEntry)->fileLinkCount > 1)
+            FileDirNdx->FI_Flags |= UDF_FI_FLAG_LINKED;
+    }
+    FCharact = FileDirNdx->FileCharacteristics;
+
+    if(Flags & ICB_FLAG_SYSTEM) NTAttr |= FILE_ATTRIBUTE_SYSTEM;
+    if(Flags & ICB_FLAG_ARCHIVE) NTAttr |= FILE_ATTRIBUTE_ARCHIVE;
+    if((Type == UDF_FILE_TYPE_DIRECTORY) ||
+       (Type == UDF_FILE_TYPE_STREAMDIR) ||
+       (FCharact & FILE_DIRECTORY)) {
+        NTAttr |= FILE_ATTRIBUTE_DIRECTORY;
+#ifdef UDF_DBG
+    } else {
+        //NTAttr |= FILE_ATTRIBUTE_NORMAL;
+#endif
+    }
+    if(FCharact & FILE_HIDDEN) NTAttr |= FILE_ATTRIBUTE_HIDDEN;
+    if( !(attr & PERM_O_WRITE) &&
+        !(attr & PERM_G_WRITE) &&
+        !(attr & PERM_U_WRITE) &&
+        !(attr & PERM_O_DELETE) &&
+        !(attr & PERM_G_DELETE) &&
+        !(attr & PERM_U_DELETE) ) {
+        NTAttr |= FILE_ATTRIBUTE_READONLY;
+    }
+    FileDirNdx->SysAttr = NTAttr;
+    return NTAttr;
+} // end UDFAttributesToNT()
+
+/*
+ */
+VOID
+UDFAttributesToUDF(
+    IN PDIR_INDEX_ITEM FileDirNdx,
+    IN tag* FileEntry,
+    IN ULONG NTAttr
+    )
+{
+    PULONG attr; //permissions
+    PUSHORT Flags;
+    PUCHAR Type;
+    PUCHAR FCharact;
+
+    NTAttr &= UDF_VALID_FILE_ATTRIBUTES;
+
+    if(!FileEntry) {
+        ASSERT(FileDirNdx);
+        if(!FileDirNdx->FileInfo)
+            return;
+        ValidateFileInfo(FileDirNdx->FileInfo);
+        FileEntry = FileDirNdx->FileInfo->Dloc->FileEntry;
+        FileDirNdx->FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
+    }
+    if(FileEntry->tagIdent == TID_FILE_ENTRY) {
+        attr = &((PFILE_ENTRY)FileEntry)->permissions;
+        Flags = &((PFILE_ENTRY)FileEntry)->icbTag.flags;
+        Type = &((PFILE_ENTRY)FileEntry)->icbTag.fileType;
+    } else {
+        attr = &((PEXTENDED_FILE_ENTRY)FileEntry)->permissions;
+        Flags = &((PEXTENDED_FILE_ENTRY)FileEntry)->icbTag.flags;
+        Type = &((PEXTENDED_FILE_ENTRY)FileEntry)->icbTag.fileType;
+    }
+    FCharact = &(FileDirNdx->FileCharacteristics);
+
+    if((*FCharact & FILE_DIRECTORY) ||
+       (*Type == UDF_FILE_TYPE_STREAMDIR) || 
+       (*Type == UDF_FILE_TYPE_DIRECTORY)) {
+        *FCharact |= FILE_DIRECTORY;
+        if(*Type != UDF_FILE_TYPE_STREAMDIR)
+            *Type = UDF_FILE_TYPE_DIRECTORY;
+        *attr |= (PERM_O_EXEC | PERM_G_EXEC | PERM_U_EXEC);
+        NTAttr |= FILE_ATTRIBUTE_DIRECTORY;
+        NTAttr &= ~FILE_ATTRIBUTE_NORMAL;
+    } else {
+        *FCharact &= ~FILE_DIRECTORY;
+        *Type = UDF_FILE_TYPE_REGULAR;
+        *attr &= ~(PERM_O_EXEC | PERM_G_EXEC | PERM_U_EXEC);
+    }
+
+    if(NTAttr & FILE_ATTRIBUTE_SYSTEM) {
+        *Flags |= ICB_FLAG_SYSTEM;
+    } else {
+        *Flags &= ~ICB_FLAG_SYSTEM;
+    }
+    if(NTAttr & FILE_ATTRIBUTE_ARCHIVE) {
+        *Flags |= ICB_FLAG_ARCHIVE;
+    } else {
+        *Flags &= ~ICB_FLAG_ARCHIVE;
+    }
+    if(NTAttr & FILE_ATTRIBUTE_HIDDEN) {
+       *FCharact |= FILE_HIDDEN;
+    } else {
+       *FCharact &= ~FILE_HIDDEN;
+    }
+    *attr |= (PERM_O_READ | PERM_G_READ | PERM_U_READ);
+    if(!(NTAttr & FILE_ATTRIBUTE_READONLY)) {
+        *attr |= (PERM_O_WRITE  | PERM_G_WRITE  | PERM_U_WRITE |
+                  PERM_O_DELETE | PERM_G_DELETE | PERM_U_DELETE |
+                  PERM_O_CHATTR | PERM_G_CHATTR | PERM_U_CHATTR);
+    } else {
+        *attr &= ~(PERM_O_WRITE  | PERM_G_WRITE  | PERM_U_WRITE |
+                   PERM_O_DELETE | PERM_G_DELETE | PERM_U_DELETE |
+                   PERM_O_CHATTR | PERM_G_CHATTR | PERM_U_CHATTR);
+    }
+    FileDirNdx->SysAttr = NTAttr;
+    if(FileDirNdx->FileInfo)
+        FileDirNdx->FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
+    FileDirNdx->FI_Flags |= UDF_FI_FLAG_FI_MODIFIED;
+    return;
+} // end UDFAttributesToUDF()
+
+#ifndef _CONSOLE
+/*
+    This routine fills PFILE_BOTH_DIR_INFORMATION structure (NT)
+ */
+NTSTATUS
+UDFFileDirInfoToNT(
+    IN PVCB Vcb,
+    IN PDIR_INDEX_ITEM FileDirNdx,
+    OUT PFILE_BOTH_DIR_INFORMATION NTFileInfo
+    )
+{
+    PFILE_ENTRY FileEntry;
+    UNICODE_STRING UdfName;
+    UNICODE_STRING DosName;
+    PEXTENDED_FILE_ENTRY ExFileEntry;
+    USHORT Ident;
+    BOOLEAN ReadSizes;
+    NTSTATUS status;
+    PtrUDFNTRequiredFCB NtReqFcb;
+
+    KdPrint(("@=%#x, FileDirNdx %x\n", &Vcb, FileDirNdx));
+
+    ASSERT((ULONG)NTFileInfo > 0x1000);
+    RtlZeroMemory(NTFileInfo, sizeof(FILE_BOTH_DIR_INFORMATION));
+    
+    DosName.Buffer = (PWCHAR)&(NTFileInfo->ShortName);
+    DosName.MaximumLength = sizeof(NTFileInfo->ShortName); // 12*sizeof(WCHAR)
+
+    _SEH2_TRY {
+        KdPrint(("  DirInfoToNT: %*.*S\n", FileDirNdx->FName.Length/sizeof(WCHAR), FileDirNdx->FName.Length/sizeof(WCHAR), FileDirNdx->FName));
+    } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+        KdPrint(("  DirInfoToNT: exception when printing file name\n"));
+    } _SEH2_END;
+
+    if(FileDirNdx->FileInfo) {
+        KdPrint(("    FileInfo\n"));
+        // validate FileInfo
+        ValidateFileInfo(FileDirNdx->FileInfo);
+        if(UDFGetFileLinkCount(FileDirNdx->FileInfo) > 1)
+            FileDirNdx->FI_Flags |= UDF_FI_FLAG_LINKED;
+        FileEntry = (PFILE_ENTRY)(FileDirNdx->FileInfo->Dloc->FileEntry);
+        // read required sizes from Fcb (if any) if file is not linked
+        // otherwise we should read them from FileEntry
+        if(FileDirNdx->FileInfo->Fcb) {
+            KdPrint(("    Fcb\n"));
+            NtReqFcb = FileDirNdx->FileInfo->Fcb->NTRequiredFCB;
+            NTFileInfo->CreationTime.QuadPart   = NtReqFcb->CreationTime.QuadPart;
+            NTFileInfo->LastWriteTime.QuadPart  = NtReqFcb->LastWriteTime.QuadPart;
+            NTFileInfo->LastAccessTime.QuadPart = NtReqFcb->LastAccessTime.QuadPart;
+            NTFileInfo->ChangeTime.QuadPart     = NtReqFcb->ChangeTime.QuadPart;
+//            NTFileInfo->AllocationSize.QuadPart = NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart;
+            NTFileInfo->AllocationSize.QuadPart = FileDirNdx->AllocationSize;
+/*            FileDirNdx->FileSize =
+            NTFileInfo->EndOfFile.QuadPart = NtReqFcb->CommonFCBHeader.FileSize.QuadPart;*/
+            NTFileInfo->EndOfFile.QuadPart = FileDirNdx->FileSize;
+            if(FileDirNdx->FI_Flags & UDF_FI_FLAG_SYS_ATTR) {
+                KdPrint(("    SYS_ATTR\n"));
+                NTFileInfo->FileAttributes = FileDirNdx->SysAttr;
+                goto get_name_only;
+            }
+            FileDirNdx->CreationTime   = NTFileInfo->CreationTime.QuadPart;
+            FileDirNdx->LastWriteTime  = NTFileInfo->LastWriteTime.QuadPart;
+            FileDirNdx->LastAccessTime = NTFileInfo->LastAccessTime.QuadPart;
+            FileDirNdx->ChangeTime     = NTFileInfo->ChangeTime.QuadPart;
+            goto get_attr_only;
+        }
+        ASSERT(FileEntry);
+    } else if(!(FileDirNdx->FI_Flags & UDF_FI_FLAG_SYS_ATTR) ||
+               (FileDirNdx->FI_Flags & UDF_FI_FLAG_LINKED)) {
+        LONG_AD feloc;
+
+        KdPrint(("  !SYS_ATTR\n"));
+        FileEntry = (PFILE_ENTRY)MyAllocatePool__(NonPagedPool, Vcb->LBlockSize);
+        if(!FileEntry) return STATUS_INSUFFICIENT_RESOURCES;
+
+        feloc.extLength = Vcb->LBlockSize;
+        feloc.extLocation = FileDirNdx->FileEntryLoc;
+
+        if(!NT_SUCCESS(status = UDFReadFileEntry(Vcb, &feloc, FileEntry, &Ident))) {
+            KdPrint(("    !UDFReadFileEntry\n"));
+            MyFreePool__(FileEntry);
+            FileEntry = NULL;
+            goto get_name_only;
+        }
+        ReadSizes = TRUE;
+    } else {
+        KdPrint(("  FileDirNdx\n"));
+        NTFileInfo->CreationTime.QuadPart   = FileDirNdx->CreationTime;
+        NTFileInfo->LastWriteTime.QuadPart  = FileDirNdx->LastWriteTime;
+        NTFileInfo->LastAccessTime.QuadPart = FileDirNdx->LastAccessTime;
+        NTFileInfo->ChangeTime.QuadPart     = FileDirNdx->ChangeTime;
+        NTFileInfo->FileAttributes = FileDirNdx->SysAttr;
+        NTFileInfo->AllocationSize.QuadPart = FileDirNdx->AllocationSize;
+        NTFileInfo->EndOfFile.QuadPart = FileDirNdx->FileSize;
+        NTFileInfo->EaSize = 0;
+        FileEntry = NULL;
+        goto get_name_only;
+    }
+
+    if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)
+        goto get_name_only;
+
+    KdPrint(("  direct\n"));
+    if(FileEntry->descTag.tagIdent == TID_FILE_ENTRY) {
+        KdPrint(("  TID_FILE_ENTRY\n"));
+        if(ReadSizes) {
+            KdPrint(("    ReadSizes\n"));
+            // Times
+            FileDirNdx->CreationTime   = NTFileInfo->CreationTime.QuadPart   =
+            FileDirNdx->LastWriteTime  = NTFileInfo->LastWriteTime.QuadPart  = UDFTimeToNT(&(FileEntry->modificationTime));
+            FileDirNdx->LastAccessTime = NTFileInfo->LastAccessTime.QuadPart = UDFTimeToNT(&(FileEntry->accessTime));
+            FileDirNdx->ChangeTime     = NTFileInfo->ChangeTime.QuadPart     = UDFTimeToNT(&(FileEntry->attrTime));
+            // FileSize
+            FileDirNdx->FileSize =
+            NTFileInfo->EndOfFile.QuadPart =
+                FileEntry->informationLength;
+            KdPrint(("    informationLength=%I64x, lengthAllocDescs=%I64x\n",
+                FileEntry->informationLength,
+                FileEntry->lengthAllocDescs
+                ));
+            // AllocSize
+            FileDirNdx->AllocationSize =
+            NTFileInfo->AllocationSize.QuadPart =
+                (FileEntry->informationLength + Vcb->LBlockSize - 1) & ~((LONGLONG)(Vcb->LBlockSize) - 1);
+        }
+//        NTFileInfo->EaSize = 0;//FileEntry->lengthExtendedAttr;
+    } else if(FileEntry->descTag.tagIdent == TID_EXTENDED_FILE_ENTRY) {
+        ExFileEntry = (PEXTENDED_FILE_ENTRY)FileEntry;
+        KdPrint(("  PEXTENDED_FILE_ENTRY\n"));
+        if(ReadSizes) {
+            KdPrint(("    ReadSizes\n"));
+            // Times
+            FileDirNdx->CreationTime   = NTFileInfo->CreationTime.QuadPart   = UDFTimeToNT(&(ExFileEntry->createTime));
+            FileDirNdx->LastWriteTime  = NTFileInfo->LastWriteTime.QuadPart  = UDFTimeToNT(&(ExFileEntry->modificationTime));
+            FileDirNdx->LastAccessTime = NTFileInfo->LastAccessTime.QuadPart = UDFTimeToNT(&(ExFileEntry->accessTime));
+            FileDirNdx->ChangeTime     = NTFileInfo->ChangeTime.QuadPart     = UDFTimeToNT(&(ExFileEntry->attrTime));
+            // FileSize
+            FileDirNdx->FileSize =
+            NTFileInfo->EndOfFile.QuadPart =
+                ExFileEntry->informationLength;
+            KdPrint(("    informationLength=%I64x, lengthAllocDescs=%I64x\n",
+                FileEntry->informationLength,
+                FileEntry->lengthAllocDescs
+                ));
+            // AllocSize
+            FileDirNdx->AllocationSize =
+            NTFileInfo->AllocationSize.QuadPart =
+                (ExFileEntry->informationLength + Vcb->LBlockSize - 1) & ~((LONGLONG)(Vcb->LBlockSize) - 1);
+        }
+//        NTFileInfo->EaSize = 0;//ExFileEntry->lengthExtendedAttr;
+    } else {
+        KdPrint(("  ???\n"));
+        goto get_name_only;
+    }
+
+get_attr_only:
+
+    KdPrint(("  get_attr"));
+    // do some substitutions
+    if(!FileDirNdx->CreationTime) {
+        FileDirNdx->CreationTime = NTFileInfo->CreationTime.QuadPart = Vcb->VolCreationTime;
+    }
+    if(!FileDirNdx->LastAccessTime) {
+        FileDirNdx->LastAccessTime = NTFileInfo->LastAccessTime.QuadPart = FileDirNdx->CreationTime;
+    }
+    if(!FileDirNdx->LastWriteTime) {
+        FileDirNdx->LastWriteTime = NTFileInfo->LastWriteTime.QuadPart = FileDirNdx->CreationTime;
+    }
+    if(!FileDirNdx->ChangeTime) {
+        FileDirNdx->ChangeTime = NTFileInfo->ChangeTime.QuadPart = FileDirNdx->CreationTime;
+    }
+
+    FileDirNdx->SysAttr =
+    NTFileInfo->FileAttributes = UDFAttributesToNT(FileDirNdx, (tag*)FileEntry);
+    FileDirNdx->FI_Flags |= UDF_FI_FLAG_SYS_ATTR;
+
+get_name_only:
+    // get filename in standard Unicode format
+    UdfName = FileDirNdx->FName;
+    NTFileInfo->FileNameLength = UdfName.Length;
+    RtlCopyMemory((PCHAR)&(NTFileInfo->FileName), (PCHAR)(UdfName.Buffer), UdfName.MaximumLength);
+    if(!(FileDirNdx->FI_Flags & UDF_FI_FLAG_DOS)) {
+        KdPrint(("  !UDF_FI_FLAG_DOS"));
+        UDFDOSName(Vcb, &DosName, &UdfName,
+            (FileDirNdx->FI_Flags & UDF_FI_FLAG_KEEP_NAME) ? TRUE : FALSE);
+        NTFileInfo->ShortNameLength = (UCHAR)DosName.Length;
+    }
+    // report zero EOF & AllocSize for Dirs
+    if(FileDirNdx->FileCharacteristics & FILE_DIRECTORY) {
+        KdPrint(("  FILE_DIRECTORY"));
+        NTFileInfo->AllocationSize.QuadPart =
+        NTFileInfo->EndOfFile.QuadPart = 0;
+    }
+    KdPrint(("  AllocationSize=%I64x, NTFileInfo->EndOfFile=%I64x", NTFileInfo->AllocationSize.QuadPart, NTFileInfo->EndOfFile.QuadPart));
+    // free tmp buffer (if any)
+    KdPrint(("\n"));
+    if(FileEntry && !FileDirNdx->FileInfo)
+        MyFreePool__(FileEntry);
+    return STATUS_SUCCESS;
+} // end UDFFileDirInfoToNT()
+
+#endif //_CONSOLE
+
+#ifndef UDF_READ_ONLY_BUILD
+/*
+    This routine changes xxxTime field(s) in (Ext)FileEntry
+ */
+VOID
+UDFSetFileXTime(
+    IN PUDF_FILE_INFO FileInfo,
+    IN LONGLONG* CrtTime,
+    IN LONGLONG* AccTime,
+    IN LONGLONG* AttrTime,
+    IN LONGLONG* ChgTime
+    )
+{
+    USHORT Ident;
+    PDIR_INDEX_ITEM DirNdx;
+
+    ValidateFileInfo(FileInfo);
+
+    FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
+    DirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(FileInfo), FileInfo->Index);
+    Ident = FileInfo->Dloc->FileEntry->tagIdent;
+
+    if(Ident == TID_FILE_ENTRY) {
+        PFILE_ENTRY fe = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
+
+        if(AccTime) {
+            if(DirNdx && *AccTime) DirNdx->LastAccessTime = *AccTime;
+            UDFTimeToUDF(*AccTime, &(fe->accessTime));
+        }
+        if(AttrTime) {
+            if(DirNdx && *AttrTime) DirNdx->ChangeTime = *AttrTime;
+            UDFTimeToUDF(*AttrTime, &(fe->attrTime));
+        }
+        if(ChgTime) {
+            if(DirNdx && *ChgTime) DirNdx->CreationTime =
+                DirNdx->LastWriteTime = *ChgTime;
+            UDFTimeToUDF(*ChgTime, &(fe->modificationTime));
+        } else
+        if(CrtTime) {
+            if(DirNdx && *CrtTime) DirNdx->CreationTime =
+                DirNdx->LastWriteTime = *CrtTime;
+            UDFTimeToUDF(*CrtTime, &(fe->modificationTime));
+        }
+
+    } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
+        PEXTENDED_FILE_ENTRY fe = (PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry);
+
+        if(AccTime) {
+            if(DirNdx && *AccTime) DirNdx->LastAccessTime = *AccTime;
+            UDFTimeToUDF(*AccTime, &(fe->accessTime));
+        }
+        if(AttrTime) {
+            if(DirNdx && *AttrTime) DirNdx->ChangeTime = *AttrTime;
+            UDFTimeToUDF(*AttrTime, &(fe->attrTime));
+        }
+        if(ChgTime) {
+            if(DirNdx && *ChgTime) DirNdx->LastWriteTime = *ChgTime;
+            UDFTimeToUDF(*ChgTime, &(fe->modificationTime));
+        }
+        if(CrtTime) {
+            if(DirNdx && *CrtTime) DirNdx->CreationTime = *CrtTime;
+            UDFTimeToUDF(*CrtTime, &(fe->createTime));
+        }
+
+    }
+} // end UDFSetFileXTime()
+#endif //UDF_READ_ONLY_BUILD
+
+/*
+    This routine gets xxxTime field(s) in (Ext)FileEntry
+ */
+VOID
+UDFGetFileXTime(
+    IN PUDF_FILE_INFO FileInfo,
+    OUT LONGLONG* CrtTime,
+    OUT LONGLONG* AccTime,
+    OUT LONGLONG* AttrTime,
+    OUT LONGLONG* ChgTime
+    )
+{
+    USHORT Ident;
+
+    ValidateFileInfo(FileInfo);
+
+    Ident = FileInfo->Dloc->FileEntry->tagIdent;
+
+    if(Ident == TID_FILE_ENTRY) {
+        PFILE_ENTRY fe = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
+
+        if(AccTime) *AccTime = UDFTimeToNT(&(fe->accessTime));
+        if(AttrTime) *AttrTime = UDFTimeToNT(&(fe->attrTime));
+        if(ChgTime) *ChgTime = UDFTimeToNT(&(fe->modificationTime));
+        if(CrtTime) {
+            (*CrtTime) = *ChgTime;
+        }
+
+    } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
+        PEXTENDED_FILE_ENTRY fe = (PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry);
+
+        if(AccTime) *AccTime = UDFTimeToNT(&(fe->accessTime));
+        if(AttrTime) *AttrTime = UDFTimeToNT(&(fe->attrTime));
+        if(ChgTime) *ChgTime = UDFTimeToNT(&(fe->modificationTime));
+        if(CrtTime) *CrtTime = UDFTimeToNT(&(fe->createTime));
+
+    }
+    if(CrtTime) {
+        if(!(*CrtTime)) 
+            KeQuerySystemTime((PLARGE_INTEGER)CrtTime);
+        if(AccTime && !(*AccTime)) (*AccTime) = *CrtTime;
+        if(AttrTime && !(*AttrTime)) (*AttrTime) = *CrtTime;
+        if(AccTime && !(*AccTime)) (*AccTime) = *CrtTime;
+    }
+} // end UDFGetFileXTime()
+
+VOID
+UDFNormalizeFileName(
+    IN PUNICODE_STRING FName,
+    IN USHORT valueCRC
+    )
+{
+    PWCHAR buffer;
+    USHORT len;
+
+    len = FName->Length/sizeof(WCHAR);
+    buffer = FName->Buffer;
+
+    // check for '',  '.'  &  '..'
+    if(!len) return;
+    if(!buffer[len-1]) {
+        FName->Length-=sizeof(WCHAR);
+        len--;
+    }
+    if(!len) return;
+    if(buffer[0] == UNICODE_PERIOD) {
+        if(len == 1) return;
+        if((buffer[1] == UNICODE_PERIOD) && (len == 2)) return;
+    }
+
+    // check for trailing '.'
+    for(len--;len;len--) {
+        if( ((buffer[len] == UNICODE_PERIOD) || (buffer[len] == UNICODE_SPACE)) ) {
+            FName->Length-=sizeof(WCHAR);
+            buffer[len] = 0;
+        } else
+            break;
+    }
+} // end UDFNormalizeFileName()
+
+#ifndef _CONSOLE
+
+void 
+__fastcall
+UDFDOSNameOsNative(
+    IN OUT PUNICODE_STRING DosName,
+    IN PUNICODE_STRING UdfName,
+    IN BOOLEAN KeepIntact
+    )
+{
+    PWCHAR dosName = DosName->Buffer;
+    PWCHAR udfName = UdfName->Buffer;
+    uint32 udfLen = UdfName->Length / sizeof(WCHAR);
+    GENERATE_NAME_CONTEXT Ctx;
+
+    if(KeepIntact &&
+       (udfLen <= 2) && (udfName[0] == UNICODE_PERIOD)) {
+        if((udfLen != 2) || (udfName[1] == UNICODE_PERIOD)) {
+            RtlCopyMemory(dosName, udfName, UdfName->Length);
+            DosName->Length = UdfName->Length;
+            return;
+        }
+    }
+    RtlZeroMemory(&Ctx, sizeof(GENERATE_NAME_CONTEXT));
+    RtlGenerate8dot3Name(UdfName, FALSE, &Ctx, DosName);
+    
+} // UDFDOSNameOsNative()
+
+#endif //_CONSOLE
+
+/*VOID
+UDFNormalizeFileName(
+    IN PUNICODE_STRING FName,
+    IN USHORT valueCRC
+    )
+{
+    WCHAR _newName[UDF_NAME_LEN+5];
+    PWCHAR newName = (PWCHAR)(&_newName);
+    PWCHAR udfName = FName->Buffer;
+    LONG udfLen = FName->Length >> 1;
+
+    LONG index, newIndex = 0, extIndex = 0, newExtIndex = 0, trailIndex = 0;
+    BOOLEAN needsCRC = FALSE, hasExt = FALSE;
+    WCHAR ext[UDF_EXT_SIZE], current;
+
+    // handle CurrentDir ('.') and ParentDir ('..') cases
+    if((udfLen <= 2) && (udfName[0] == UNICODE_PERIOD)) {
+        if((udfLen != 2) || (udfName[1] == UNICODE_PERIOD))
+            return;
+    }
+
+    for (index = 0 ; index < udfLen ; index++) {
+        current = udfName[index];
+
+        // Look for illegal or unprintable characters.
+        if (UDFIsIllegalChar(current) || !UnicodeIsPrint(current)) {
+            needsCRC = TRUE;
+            current = ILLEGAL_CHAR_MARK;
+            // Skip Illegal characters(even spaces),
+            // but not periods.
+            while(index+1 < udfLen &&
+                  (UDFIsIllegalChar(udfName[index+1]) ||
+                  !UnicodeIsPrint(udfName[index+1])) &&
+                  udfName[index+1] != UNICODE_PERIOD)
+                index++;
+        }
+
+        // Record position of extension, if one is found.
+        if ((current == UNICODE_PERIOD) && ((udfLen - index -1) <= UDF_EXT_SIZE)) {
+            if (udfLen == index + 1) {
+                // A trailing period is NOT an extension.
+                hasExt = FALSE;
+            } else {
+                hasExt = TRUE;
+                extIndex = index;
+                newExtIndex = newIndex;
+            }
+        } else if((current != UNICODE_PERIOD) && (current != UNICODE_SPACE)) {
+            trailIndex = index;
+        }
+
+//        if (newIndex < MAXLEN)  // tshi is always TRUE for WINNT
+        newName[newIndex] = current;
+        newIndex++;
+
+        // For OS2, 95 & NT, truncate any trailing periods and\or spaces.
+        if (trailIndex != (newIndex - 1)) {
+            newIndex = trailIndex + 1;
+            needsCRC = TRUE;
+            hasExt = FALSE; //* Trailing period does not make an extension.
+        }
+    }
+
+    if (needsCRC) {
+        int localExtIndex = 0;
+        if (hasExt) {
+            int maxFilenameLen;
+            //* Translate extension, and store it in ext. 
+            for(index = 0; index<UDF_EXT_SIZE && extIndex + index +1 < udfLen; index++ ) {
+                current = udfName[extIndex + index + 1];
+                if (UDFIsIllegalChar(current) /*|| !UnicodeIsPrint(current)) {
+                    needsCRC = TRUE;
+                    // Replace Illegal and non-displayable chars
+                    // with underscore.
+                    current = ILLEGAL_CHAR_MARK;
+                    // Skip any other illegal or non-displayable
+                    // characters.
+                    while(index + 1 < UDF_EXT_SIZE &&
+                          (UDFIsIllegalChar(udfName[extIndex + index + 2]) ||
+                          !UnicodeIsPrint(udfName[extIndex + index + 2])) )
+                        index++;
+                }
+                ext[localExtIndex++] = current;
+            }
+            // Truncate filename to leave room for extension and CRC.
+            maxFilenameLen = ((UDF_NAME_LEN - 4) - localExtIndex - 1);
+            if (newIndex > maxFilenameLen) {
+                newIndex = maxFilenameLen;
+            } else {
+                newIndex = newExtIndex;
+            }
+        } else if (newIndex > UDF_NAME_LEN - 5) {
+            //If no extension, make sure to leave room for CRC.
+            newIndex = UDF_NAME_LEN - 5;
+        }
+        newName[newIndex++] = UNICODE_CRC_MARK; // Add mark for CRC. 
+        //Calculate CRC from original filename from FileIdentifier.
+//        valueCRC = UDFUnicodeCksum(fidName, fidNameLen);
+//        / Convert 16-bits of CRC to hex characters. 
+        newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
+        newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8];
+        newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4];
+        newName[newIndex++] = hexChar[(valueCRC & 0x000f)];
+        // Place a translated extension at end, if found. 
+        if (hasExt) {
+            newName[newIndex++] = UNICODE_PERIOD;
+            for (index = 0;index < localExtIndex ;index++ ) {
+                newName[newIndex++] = ext[index];
+            }
+        }
+    }
+
+    if(FName->Length == (USHORT)newIndex*sizeof(WCHAR)) {
+        RtlCopyMemory(FName->Buffer, newName, newIndex*sizeof(WCHAR));
+        return;
+    }
+    MyFreePool__(FName->Buffer);
+    FName->Buffer = (PWCHAR)MyAllocatePool__(UDF_FILENAME_MT, (newIndex+1)*sizeof(WCHAR));
+    if(FName->Buffer) {
+        FName->Buffer[newIndex] = 0;
+        RtlCopyMemory(FName->Buffer, newName, newIndex*sizeof(WCHAR));
+    }
+    FName->Length = (USHORT)newIndex*sizeof(WCHAR);
+    FName->MaximumLength = (USHORT)(newIndex+1)*sizeof(WCHAR);
+}*/
+
+/*PUDF_FILE_INFO
+UDFAllocFileInfo(
+    return ExAllocateFromZone(&(UDFGlobalData.FileInfoZoneHeader));
+)*/
+
+#define STRING_BUFFER_ALIGNMENT  (32)
+#define STRING_BUFFER_ALIGN(sz)  (((sz)+STRING_BUFFER_ALIGNMENT)&(~((ULONG)(STRING_BUFFER_ALIGNMENT-1))))
+
+NTSTATUS
+MyAppendUnicodeStringToString_(
+    IN PUNICODE_STRING Str1,
+    IN PUNICODE_STRING Str2
+#ifdef UDF_TRACK_UNICODE_STR
+   ,IN PCHAR Tag
+#endif 
+    )
+{
+    PWCHAR tmp;
+    USHORT i;
+
+#ifdef UDF_TRACK_UNICODE_STR
+  #define UDF_UNC_STR_TAG Tag
+#else
+  #define UDF_UNC_STR_TAG "AppUStr"
+#endif 
+
+    tmp = Str1->Buffer;
+    i = Str1->Length + Str2->Length + sizeof(WCHAR);
+    ASSERT(Str1->MaximumLength);
+    if(i > Str1->MaximumLength) {
+        if(!MyReallocPool__((PCHAR)tmp, Str1->MaximumLength,
+                         (PCHAR*)&tmp, STRING_BUFFER_ALIGN(i)*2) ) {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+        Str1->MaximumLength = i*2;
+        Str1->Buffer = tmp;
+    }
+    RtlCopyMemory(((PCHAR)tmp)+Str1->Length, Str2->Buffer, Str2->Length);
+
+/*    tmp = (PWCHAR)MyAllocatePoolTag__(NonPagedPool, i = Str1->Length + Str2->Length + sizeof(WCHAR), UDF_UNC_STR_TAG);
+    if(!tmp)
+        return STATUS_INSUFFICIENT_RESOURCES;
+    RtlCopyMemory(tmp, Str1->Buffer, Str1->Length);
+    RtlCopyMemory(((PCHAR)tmp)+Str1->Length, Str2->Buffer, Str2->Length);*/
+    tmp[(i / sizeof(WCHAR)) - 1] = 0;
+    Str1->Length = i - sizeof(WCHAR);
+    //MyFreePool__(Str1->Buffer);
+#ifdef UDF_DBG
+    if(Str1->Buffer && (Str1->Length >= 2*sizeof(WCHAR))) {
+        ASSERT((Str1->Buffer[0] != L'\\') || (Str1->Buffer[1] != L'\\'));
+    }
+#endif // UDF_DBG
+    return STATUS_SUCCESS;
+
+#undef UDF_UNC_STR_TAG
+
+} // end MyAppendUnicodeStringToString()
+
+NTSTATUS
+MyAppendUnicodeToString_(
+    IN PUNICODE_STRING Str1,
+    IN PWSTR Str2
+#ifdef UDF_TRACK_UNICODE_STR
+   ,IN PCHAR Tag
+#endif 
+    )
+{
+    PWCHAR tmp;
+    USHORT i;
+
+#ifdef UDF_TRACK_UNICODE_STR
+  #define UDF_UNC_STR_TAG Tag
+#else
+  #define UDF_UNC_STR_TAG "AppStr"
+#endif 
+
+//#ifdef _X86_
+#ifdef _MSC_VER
+
+    __asm push  ebx
+    __asm push  esi
+
+    __asm xor   ebx,ebx
+    __asm mov   esi,Str2
+Scan_1:
+    __asm cmp   [word ptr esi+ebx],0
+    __asm je    EO_Scan
+    __asm add   ebx,2
+    __asm jmp   Scan_1
+EO_Scan:
+    __asm mov   i,bx
+
+    __asm pop   esi
+    __asm pop   ebx
+
+#else   // NO X86 optimization, use generic C/C++
+
+    i=0;
+    while(Str2[i]) {
+       i++;
+    }
+    i *= sizeof(WCHAR);
+
+#endif // _X86_
+
+    tmp = Str1->Buffer;
+    ASSERT(Str1->MaximumLength);
+    if((Str1->Length+i+sizeof(WCHAR)) > Str1->MaximumLength) {
+        if(!MyReallocPool__((PCHAR)tmp, Str1->MaximumLength,
+                         (PCHAR*)&tmp, STRING_BUFFER_ALIGN(i + Str1->Length + sizeof(WCHAR))*2 ) ) {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+        Str1->MaximumLength = STRING_BUFFER_ALIGN(i + sizeof(WCHAR))*2;
+        Str1->Buffer = tmp;
+    }
+    RtlCopyMemory(((PCHAR)tmp)+Str1->Length, Str2, i);
+    i+=Str1->Length;
+    tmp[(i / sizeof(WCHAR))] = 0;
+    Str1->Length = i;
+#ifdef UDF_DBG
+/*    if(Str1->Buffer && (Str1->Length >= 2*sizeof(WCHAR))) {
+        ASSERT((Str1->Buffer[0] != L'\\') || (Str1->Buffer[1] != L'\\'));
+    }*/
+#endif // UDF_DBG
+    return STATUS_SUCCESS;
+
+#undef UDF_UNC_STR_TAG
+
+} // end MyAppendUnicodeToString_()
+
+NTSTATUS
+MyInitUnicodeString(
+    IN PUNICODE_STRING Str1,
+    IN PCWSTR Str2
+    )
+{
+
+    USHORT i;
+
+//#ifdef _X86_
+#ifdef _MSC_VER
+
+    __asm push  ebx
+    __asm push  esi
+
+    __asm xor   ebx,ebx
+    __asm mov   esi,Str2
+Scan_1:
+    __asm cmp   [word ptr esi+ebx],0
+    __asm je    EO_Scan
+    __asm add   ebx,2
+    __asm jmp   Scan_1
+EO_Scan:
+    __asm mov   i,bx
+
+    __asm pop   esi
+    __asm pop   ebx
+
+#else   // NO X86 optimization, use generic C/C++
+
+    i=0;
+    while(Str2[i]) {
+       i++;
+    }
+    i *= sizeof(WCHAR);
+
+#endif // _X86_
+
+    Str1->MaximumLength = STRING_BUFFER_ALIGN((Str1->Length = i) + sizeof(WCHAR));
+    Str1->Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool, Str1->MaximumLength);
+    if(!Str1->Buffer)
+        return STATUS_INSUFFICIENT_RESOURCES;
+    RtlCopyMemory(Str1->Buffer, Str2, i);
+    Str1->Buffer[i/sizeof(WCHAR)] = 0;
+    return STATUS_SUCCESS;
+
+} // end MyInitUnicodeString()
+
+NTSTATUS
+MyCloneUnicodeString(
+    IN PUNICODE_STRING Str1,
+    IN PUNICODE_STRING Str2
+    )
+{
+    Str1->MaximumLength = STRING_BUFFER_ALIGN((Str1->Length = Str2->Length) + sizeof(WCHAR));
+    Str1->Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool, Str1->MaximumLength);
+    if(!Str1->Buffer)
+        return STATUS_INSUFFICIENT_RESOURCES;
+    ASSERT(Str2->Buffer);
+    RtlCopyMemory(Str1->Buffer, Str2->Buffer, Str2->Length);
+    Str1->Buffer[Str1->Length/sizeof(WCHAR)] = 0;
+    return STATUS_SUCCESS;
+
+} // end MyCloneUnicodeString()
+
+/*
+    This routine checks do we needn't read something from disk to
+    obtain Attributes & so on
+ */
+BOOLEAN
+UDFIsDirInfoCached(
+    IN PVCB Vcb,
+    IN PUDF_FILE_INFO DirInfo
+    )
+{
+    PDIR_INDEX_HDR hDirNdx = DirInfo->Dloc->DirIndex;
+    PDIR_INDEX_ITEM DirNdx;
+    for(uint_di i=2; DirNdx = UDFDirIndex(hDirNdx,i); i++) {
+        if(!(DirNdx->FI_Flags & UDF_FI_FLAG_SYS_ATTR) ||
+            (DirNdx->FI_Flags & UDF_FI_FLAG_LINKED)) return FALSE;
+    }
+    return TRUE;
+} // end UDFIsDirInfoCached()
+
+#ifndef UDF_READ_ONLY_BUILD
+NTSTATUS
+UDFDoesOSAllowFileToBeTargetForRename__(
+    IN PUDF_FILE_INFO FileInfo
+    )
+{
+#ifndef _CONSOLE
+    NTSTATUS RC;
+#endif //_CONSOLE
+
+    if(UDFIsADirectory(FileInfo))
+        return STATUS_ACCESS_DENIED;
+    if(!FileInfo->ParentFile)
+        return STATUS_ACCESS_DENIED;
+
+    if(UDFAttributesToNT(UDFDirIndex(UDFGetDirIndexByFileInfo(FileInfo),FileInfo->Index),
+                         FileInfo->Dloc->FileEntry) & FILE_ATTRIBUTE_READONLY)
+        return STATUS_ACCESS_DENIED;
+
+    if(!FileInfo->Fcb)
+        return STATUS_SUCCESS;
+#ifndef _CONSOLE
+    RC = UDFCheckAccessRights(NULL, NULL, FileInfo->Fcb, NULL, DELETE, 0);
+    if(!NT_SUCCESS(RC))
+        return RC;
+#endif //_CONSOLE
+    if(!FileInfo->Fcb)
+        return STATUS_SUCCESS;
+//    RC = UDFMarkStreamsForDeletion(FileInfo->Fcb->Vcb, FileInfo->Fcb, TRUE); // Delete
+/*    RC = UDFSetDispositionInformation(FileInfo->Fcb, NULL,
+                FileInfo->Fcb->Vcb, NULL, TRUE);
+    if(NT_SUCCESS(RC)) {
+        FileInfo->Fcb->FCBFlags |= UDF_FCB_DELETED;
+        if(UDFGetFileLinkCount(FileInfo) <= 1) {
+            FileInfo->Fcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_DELETED;
+        }
+    }
+    return RC;*/
+    return STATUS_ACCESS_DENIED;
+
+} // end UDFDoesOSAllowFileToBeTargetForRename__()
+
+NTSTATUS
+UDFDoesOSAllowFileToBeUnlinked__(
+    IN PUDF_FILE_INFO FileInfo
+    )
+{
+    PDIR_INDEX_HDR hCurDirNdx;
+    PDIR_INDEX_ITEM CurDirNdx;
+    uint_di i;
+//    IO_STATUS_BLOCK IoStatus;
+
+    ASSERT(FileInfo->Dloc);
+
+    if(!FileInfo->ParentFile)
+        return STATUS_CANNOT_DELETE;
+    if(FileInfo->Dloc->SDirInfo)
+        return STATUS_CANNOT_DELETE;
+    if(!UDFIsADirectory(FileInfo))
+        return STATUS_SUCCESS;
+
+//    UDFFlushAFile(FileInfo->Fcb, NULL, &IoStatus, 0);
+    hCurDirNdx = FileInfo->Dloc->DirIndex;
+    // check if we can delete all files
+    for(i=2; CurDirNdx = UDFDirIndex(hCurDirNdx,i); i++) {
+        // try to open Stream
+        if(CurDirNdx->FileInfo)
+            return STATUS_CANNOT_DELETE;
+    }
+//    return UDFCheckAccessRights(NULL, NULL, FileInfo->Fcb, NULL, DELETE, 0);
+    return STATUS_SUCCESS;
+} // end UDFDoesOSAllowFileToBeUnlinked__()
+
+NTSTATUS
+UDFDoesOSAllowFilePretendDeleted__(
+    IN PUDF_FILE_INFO FileInfo
+    )
+{
+    PDIR_INDEX_HDR hDirNdx = UDFGetDirIndexByFileInfo(FileInfo);
+    if(!hDirNdx) return STATUS_CANNOT_DELETE;
+    PDIR_INDEX_ITEM DirNdx = UDFDirIndex(hDirNdx, FileInfo->Index);
+    if(!DirNdx) return STATUS_CANNOT_DELETE;
+    // we can't hide file that is not marked as deleted
+    if(!(DirNdx->FileCharacteristics & FILE_DELETED)) {
+        BrutePoint();
+
+#ifndef _CONSOLE
+        if(!(FileInfo->Fcb->FCBFlags & (UDF_FCB_DELETE_ON_CLOSE |
+                                        UDF_FCB_DELETED) ))
+#endif //_CONSOLE
+
+            return STATUS_CANNOT_DELETE;
+    }
+    return STATUS_SUCCESS;
+}
+#endif //UDF_READ_ONLY_BUILD
+
diff --git a/reactos/drivers/filesystems/udfs/Include/Sys_spec_lib.h b/reactos/drivers/filesystems/udfs/Include/Sys_spec_lib.h
new file mode 100644 (file)
index 0000000..19b0327
--- /dev/null
@@ -0,0 +1,187 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+/*************************************************************************
+*
+* File: sys_spec_lib.h
+*
+* Module: UDF File System Driver (Kernel mode execution only)
+*
+* Description:
+*   The main include file for the UDF file system driver.
+*
+* Author: Alter
+*
+*************************************************************************/
+
+#ifndef _UDF_SYS_SPEC_LIB__H_
+#define _UDF_SYS_SPEC_LIB__H_
+
+typedef struct _UDF_PH_CALL_CONTEXT {
+    KEVENT          event;
+    IO_STATUS_BLOCK IosbToUse;
+} UDF_PH_CALL_CONTEXT, *PUDF_PH_CALL_CONTEXT;
+
+#ifdef _BROWSE_UDF_
+
+// convert UDF timestamp to NT time
+LONGLONG UDFTimeToNT(IN PUDF_TIME_STAMP UdfTime);
+// translate UDF file attributes to NT ones
+ULONG    UDFAttributesToNT(IN PDIR_INDEX_ITEM FileDirNdx,
+                           IN tag* FileEntry);
+// translate NT file attributes to UDF ones
+VOID     UDFAttributesToUDF(IN PDIR_INDEX_ITEM FileDirNdx,
+                            IN tag* FileEntry,
+                            IN ULONG NTAttr);
+// translate all file information to NT
+NTSTATUS UDFFileDirInfoToNT(IN PVCB Vcb,
+                            IN PDIR_INDEX_ITEM FileDirNdx,
+                            OUT PFILE_BOTH_DIR_INFORMATION NTFileInfo);
+// convert NT time to UDF timestamp
+VOID     UDFTimeToUDF(IN LONGLONG NtTime,
+                      OUT PUDF_TIME_STAMP UdfTime);
+// change xxxTime field(s) in (Ext)FileEntry
+VOID     UDFSetFileXTime(IN PUDF_FILE_INFO FileInfo,
+                         IN LONGLONG* CrtTime,
+                         IN LONGLONG* AccTime,
+                         IN LONGLONG* AttrTime,
+                         IN LONGLONG* ChgTime);
+// get xxxTime field(s) in (Ext)FileEntry
+VOID     UDFGetFileXTime(IN PUDF_FILE_INFO FileInfo,
+                         OUT LONGLONG* CrtTime,
+                         OUT LONGLONG* AccTime,
+                         OUT LONGLONG* AttrTime,
+                         OUT LONGLONG* ChgTime);
+//
+#define UDFUpdateAccessTime(Vcb, FileInfo)             \
+if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_ACCESS_TIME) {       \
+    LONGLONG NtTime;                                   \
+    KeQuerySystemTime((PLARGE_INTEGER)&NtTime);            \
+    UDFSetFileXTime(FileInfo, NULL, &NtTime, NULL, NULL);  \
+}
+//
+#define UDFUpdateModifyTime(Vcb, FileInfo)             \
+if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_MODIFY_TIME) {       \
+    LONGLONG NtTime;                                   \
+    ULONG Attr;                                        \
+    PDIR_INDEX_ITEM DirNdx;                            \
+    KeQuerySystemTime((PLARGE_INTEGER)&NtTime);               \
+    UDFSetFileXTime(FileInfo, NULL, &NtTime, NULL, &NtTime);  \
+    DirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(FileInfo), (FileInfo)->Index); \
+    Attr = UDFAttributesToNT(DirNdx, (FileInfo)->Dloc->FileEntry); \
+    if(!(Attr & FILE_ATTRIBUTE_ARCHIVE))                            \
+        UDFAttributesToUDF(DirNdx, (FileInfo)->Dloc->FileEntry, Attr); \
+}
+//
+#define UDFUpdateAttrTime(Vcb, FileInfo)               \
+if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_ATTR_TIME) {         \
+    LONGLONG NtTime;                                   \
+    KeQuerySystemTime((PLARGE_INTEGER)&NtTime);               \
+    UDFSetFileXTime(FileInfo, NULL, &NtTime, &NtTime, NULL);  \
+}
+//
+#define UDFUpdateCreateTime(Vcb, FileInfo)             \
+{                                                      \
+    LONGLONG NtTime;                                   \
+    KeQuerySystemTime((PLARGE_INTEGER)&NtTime);               \
+    UDFSetFileXTime(FileInfo, &NtTime, &NtTime, &NtTime, &NtTime);  \
+}
+
+void 
+__fastcall
+UDFDOSNameOsNative(
+    IN OUT PUNICODE_STRING DosName,
+    IN PUNICODE_STRING UdfName,
+    IN BOOLEAN KeepIntact
+    );
+
+VOID     UDFNormalizeFileName(IN PUNICODE_STRING FName,
+                              IN USHORT valueCRC);
+
+NTSTATUS MyAppendUnicodeStringToString_(IN PUNICODE_STRING Str1,
+                                        IN PUNICODE_STRING Str2
+#ifdef UDF_TRACK_UNICODE_STR
+                                       ,IN PCHAR Tag
+#endif 
+                                       );
+
+NTSTATUS MyAppendUnicodeToString_(IN PUNICODE_STRING Str1,
+                                  IN PWSTR Str2
+#ifdef UDF_TRACK_UNICODE_STR
+                                 ,IN PCHAR Tag
+#endif 
+                                 );
+
+#ifdef UDF_TRACK_UNICODE_STR
+  #define MyAppendUnicodeStringToString(s1,s2)         MyAppendUnicodeStringToString_(s1,s2,"AppUStr")
+  #define MyAppendUnicodeStringToStringTag(s1,s2,tag)  MyAppendUnicodeStringToString_(s1,s2,tag)
+  #define MyAppendUnicodeToString(s1,s2)               MyAppendUnicodeToString_(s1,s2,"AppStr")
+  #define MyAppendUnicodeToStringTag(s1,s2,tag)        MyAppendUnicodeToString_(s1,s2,tag)
+#else
+  #define MyAppendUnicodeStringToString(s1,s2)  MyAppendUnicodeStringToString_(s1,s2)
+  #define MyAppendUnicodeStringToStringTag(s1,s2,tag)  MyAppendUnicodeStringToString_(s1,s2)
+  #define MyAppendUnicodeToString(s1,s2)               MyAppendUnicodeToString_(s1,s2)
+  #define MyAppendUnicodeToStringTag(s1,s2,tag)        MyAppendUnicodeToString_(s1,s2)
+#endif
+
+NTSTATUS MyInitUnicodeString(IN PUNICODE_STRING Str1,
+                             IN PCWSTR Str2);
+
+NTSTATUS MyCloneUnicodeString(IN PUNICODE_STRING Str1,
+                              IN PUNICODE_STRING Str2);
+
+/*ULONG    MyCompareUnicodeString(PUNICODE_STRING s1,
+                                PUNICODE_STRING s2,
+                                BOOLEAN UpCase);*/
+
+/*
+#define UDFAllocFileInfo() \
+    ExAllocateFromZone(&(UDFGlobalData.FileInfoZoneHeader))
+*/
+
+#define UDFIsDataCached(Vcb,Lba,BCount) \
+    ( WCacheIsInitialized__(&((Vcb)->FastCache)) &&        \
+     (KeGetCurrentIrql() < DISPATCH_LEVEL) && \
+      WCacheIsCached__(&((Vcb)->FastCache),Lba, BCount) )
+
+BOOLEAN  UDFIsDirInfoCached(IN PVCB Vcb,
+                            IN PUDF_FILE_INFO DirInfo);
+
+#define UDFGetNTFileId(Vcb, fi, fn) (((fi)->Dloc->FELoc.Mapping[0].extLocation - UDFPartStart(Vcb, -2)) + \
+                                     ((ULONG)(UDFUnicodeCksum((fn)->Buffer, (fn)->Length/sizeof(WCHAR))) << 16) + \
+                                     ((LONGLONG)Vcb<<32) )
+
+#define UnicodeIsPrint(a) RtlIsValidOemCharacter(&(a))
+
+#define UDFSysGetAllocSize(Vcb, Size) ((Size + Vcb->LBlockSize - 1) & ~((LONGLONG)(Vcb->LBlockSize - 1)))
+
+NTSTATUS UDFDoesOSAllowFileToBeTargetForRename__(IN PUDF_FILE_INFO FileInfo);
+#define UDFDoesOSAllowFileToBeTargetForHLink__  UDFDoesOSAllowFileToBeTargetForRename__
+NTSTATUS UDFDoesOSAllowFileToBeUnlinked__(IN PUDF_FILE_INFO FileInfo);
+#define UDFDoesOSAllowFileToBeMoved__  UDFDoesOSAllowFileToBeUnlinked__
+NTSTATUS UDFDoesOSAllowFilePretendDeleted__(IN PUDF_FILE_INFO FileInfo);
+BOOLEAN UDFRemoveOSReferences__(IN PUDF_FILE_INFO FileInfo);
+
+#define UDFIsFSDevObj(DeviceObject) \
+    (DeviceObject->DeviceExtension && \
+      ( (((PVCB)(DeviceObject->DeviceExtension))->NodeIdentifier.NodeType == \
+              UDF_NODE_TYPE_UDFFS_DEVOBJ) || \
+        (((PVCB)(DeviceObject->DeviceExtension))->NodeIdentifier.NodeType == \
+              UDF_NODE_TYPE_UDFFS_DRVOBJ) \
+      ) \
+    )
+/*
+extern ULONG  MajorVersion;
+extern ULONG  MinorVersion;
+extern ULONG  BuildNumber;
+
+#define WinVer_Is351  (MajorVersion==0x03 && MinorVersion==51)
+#define WinVer_IsNT   (MajorVersion==0x04)
+#define WinVer_Is2k   (MajorVersion==0x05 && MinorVersion==0x00)
+#define WinVer_IsXP   (MajorVersion==0x05 && MinorVersion==0x01)
+#define WinVer_IsdNET (MajorVersion==0x05 && MinorVersion==0x02)
+*/
+#endif //_BROWSE_UDF_
+
+#endif  // _UDF_SYS_SPEC_LIB__H_
diff --git a/reactos/drivers/filesystems/udfs/Include/check_env.h b/reactos/drivers/filesystems/udfs/Include/check_env.h
new file mode 100644 (file)
index 0000000..96c3b36
--- /dev/null
@@ -0,0 +1,107 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifndef __CHECK_EXECUTION_ENVIRONMENT__H__
+#define __CHECK_EXECUTION_ENVIRONMENT__H__
+
+/*
+// check mode
+#ifdef NT_KERNEL_MODE
+  #ifdef NT_NATIVE_MODE
+    #error Error cannot combine Kernel and Natime
+  #endif //
+#endif //NT_KERNEL_MODE
+#ifdef NT_KERNEL_MODE
+  #if defined(NT_NATIVE_MODE) || defined(WIN_32_MODE)
+    #error !!!! Execution mode definition conflict !!!!
+  #endif //
+#endif //NT_KERNEL_MODE
+#ifdef NT_NATIVE_MODE
+  #if defined(WIN_32_MODE)
+    #error !!!! Execution mode definition conflict !!!!
+  #endif //
+#endif //NT_NATIVE_MODE
+
+// include appropriate header(s)
+#ifdef NT_KERNEL_MODE
+  
+  #ifdef NT_DEV_DRV_ENV
+    #include <ntddk.h>
+  #endif //NT_DEV_DRV_ENV
+
+  #ifdef NT_FS_DRV_ENV
+    #include <ntifs.h>
+  #endif //NT_DEV_DRV_ENV
+  #include "Include/ntddk_ex.h"
+
+  #ifdef WIN_32_ENV
+    #error Error: Win32 environment is not supported in Kernel Mode
+  #endif //WIN_32_ENV
+
+#endif //NT_KERNEL_MODE
+
+#ifdef NT_NATIVE_MODE
+  
+  #include "Include/nt_native.h"
+  #ifdef NT_DEV_DRV_ENV
+    #include "LibCdrw/env_spec_cdrw_w32.h"
+  #endif //NT_DEV_DRV_ENV
+
+  #ifdef NT_FS_DRV_ENV
+    #error Error: FS Driver environment is not supported in Native Mode
+  #endif //NT_DEV_DRV_ENV
+
+  #ifdef WIN_32_ENV
+  #endif //WIN_32_ENV
+
+#endif //NT_NATIVE_MODE
+
+#ifdef WIN_32_MODE
+
+  #include "windows.h"
+  #ifdef NT_DEV_DRV_ENV
+    #include "LibCdrw/env_spec_cdrw_w32.h"
+  #endif //NT_DEV_DRV_ENV
+
+  #ifdef NT_FS_DRV_ENV
+    #error Error: FS Driver environment is not supported in Win32 Mode
+  #endif //NT_DEV_DRV_ENV
+
+  #ifdef WIN_32_ENV
+  #endif //WIN_32_ENV
+
+#endif //WIN_32_MODE
+*/
+
+
+#ifdef NT_INCLUDED
+#define NT_KERNEL_MODE
+#endif //NT_INCLUDED
+
+#ifdef NT_NATIVE_MODE
+//#define USER_MODE
+#endif //NT_NATIVE_MODE
+
+// default to Win32 environment
+#if (!defined(NT_KERNEL_MODE) && !defined(NT_NATIVE_MODE)) || defined(WIN_32_MODE)
+//#warning !!!! Execution mode defaulted to WIN_32 !!!!
+//#define USER_MODE
+#define WIN_32_MODE
+#endif 
+
+// check mode
+#ifdef NT_KERNEL_MODE
+  #if defined(NT_NATIVE_MODE) || defined(WIN_32_MODE)
+    #error !!!! Execution mode definition conflict !!!!
+  #endif //
+#endif //NT_KERNEL_MODE
+#ifdef NT_NATIVE_MODE
+  #if defined(WIN_32_MODE)
+    #error !!!! Execution mode definition conflict !!!!
+  #endif //
+#endif //NT_NATIVE_MODE
+
+
+#endif //__CHECK_EXECUTION_ENVIRONMENT__H__
diff --git a/reactos/drivers/filesystems/udfs/Include/common.rc b/reactos/drivers/filesystems/udfs/Include/common.rc
new file mode 100644 (file)
index 0000000..3914192
--- /dev/null
@@ -0,0 +1,23 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+//+-------------------------------------------------------------------------
+//
+//  File:       common.rc
+//
+//--------------------------------------------------------------------------
+
+#include "version.h"
+
+#undef  VER_COMPANYNAME_STR
+#define VER_COMPANYNAME_STR         VER_STR_VENDOR_NAME
+#define VER_FILEDESCRIPTION_STR_HDR ""
+#define VER_LEGALCOPYRIGHT_YEARS    "1999-2008"
+#define VER_LEGALCOPYRIGHT_STR      "Copyright \251 " VER_STR_VENDOR_NAME " " VER_LEGALCOPYRIGHT_YEARS
+#undef  VER_PRODUCTNAME_STR
+#define VER_PRODUCTNAME_STR         VER_STR_PRODUCT_NAME
+#undef  VER_LEGALTRADEMARKS_STR
+
+#define VER_LANGNEUTRAL
+
diff --git a/reactos/drivers/filesystems/udfs/Include/common_dwn.rc b/reactos/drivers/filesystems/udfs/Include/common_dwn.rc
new file mode 100644 (file)
index 0000000..3914192
--- /dev/null
@@ -0,0 +1,23 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+//+-------------------------------------------------------------------------
+//
+//  File:       common.rc
+//
+//--------------------------------------------------------------------------
+
+#include "version.h"
+
+#undef  VER_COMPANYNAME_STR
+#define VER_COMPANYNAME_STR         VER_STR_VENDOR_NAME
+#define VER_FILEDESCRIPTION_STR_HDR ""
+#define VER_LEGALCOPYRIGHT_YEARS    "1999-2008"
+#define VER_LEGALCOPYRIGHT_STR      "Copyright \251 " VER_STR_VENDOR_NAME " " VER_LEGALCOPYRIGHT_YEARS
+#undef  VER_PRODUCTNAME_STR
+#define VER_PRODUCTNAME_STR         VER_STR_PRODUCT_NAME
+#undef  VER_LEGALTRADEMARKS_STR
+
+#define VER_LANGNEUTRAL
+
diff --git a/reactos/drivers/filesystems/udfs/Include/env_spec_nt.cpp b/reactos/drivers/filesystems/udfs/Include/env_spec_nt.cpp
new file mode 100644 (file)
index 0000000..310bed3
--- /dev/null
@@ -0,0 +1,595 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifdef NT_NATIVE_MODE
+
+#include "regtools.h"
+#include <stdarg.h>
+
+/*typedef BOOLEAN (*PPsGetVersion) (
+    PULONG MajorVersion OPTIONAL,
+    PULONG MinorVersion OPTIONAL,
+    PULONG BuildNumber OPTIONAL,
+    PUNICODE_STRING CSDVersion OPTIONAL
+    );
+
+//PPsGetVersion _PsGetVersion = PsGetVersion;
+
+/*NTSTATUS
+KernelGetProcAddress(
+    PWCHAR DllName,
+    PUCHAR ProcName,
+    PVOID* ProcAddr
+    )
+{
+  NTSTATUS RC;
+  HANDLE h;
+  UNICODE_STRING uname;
+  ANSI_STRING aname;
+
+  RtlInitUnicodeString(&uname, DllName);
+  *ProcAddr = NULL;
+
+ // RC = LdrGetDllHandle(NULL, NULL, &uname, &h);
+  if(!NT_SUCCESS(RC))
+    return RC;
+
+  RtlInitAnsiString(&aname, ProcName);
+  
+//  RC = LdrGetProcedureAddress(h, &aname, 0, ProcAddr);
+  return RC;
+} */
+
+
+BOOLEAN
+GetOsVersion(
+    PULONG MajorVersion OPTIONAL,
+    PULONG MinorVersion OPTIONAL,
+    PULONG BuildNumber OPTIONAL,
+    PUNICODE_STRING CSDVersion OPTIONAL
+    )
+{
+  WCHAR Str[32];
+  ULONG mn=0, mj=0, bld=0;
+
+//  if(_PsGetVersion)
+//    return _PsGetVersion(MajorVersion, MinorVersion, BuildNumber, CSDVersion);
+
+  RtlZeroMemory(Str, sizeof(Str));
+  if(RegTGetStringValue(NULL, L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
+                                   L"CurrentVersion",
+                                   &Str[0], sizeof(Str)-sizeof(WCHAR))) {
+    ULONG i=0;
+    WCHAR a;
+    while(a = Str[i]) {
+      if(a == '.')
+        break;
+      if(a < '0' || a > '9')
+        break;
+      mj = mj*16 + (a-'0');
+      i++;
+    }
+    i++;
+    while(a = Str[i]) {
+      if(a == '.')
+        break;
+      if(a < '0' || a > '9')
+        break;
+      mn = mn*16 + (a-'0');
+      i++;
+    }
+  }
+
+  if(RegTGetStringValue(NULL, L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
+                                   L"CurrentBuildNumber",
+                                   &Str[0], sizeof(Str)-sizeof(WCHAR))) {
+    ULONG i=0;
+    WCHAR a;
+    while(a = Str[i]) {
+      if(a < '0' || a > '9')
+        break;
+      bld = bld*10 + (a-'0');
+      i++;
+    }
+  }
+  if(MajorVersion)
+    *MajorVersion = mj;
+  if(MinorVersion)
+    *MinorVersion = mn;
+  if(BuildNumber)
+    *BuildNumber = bld;
+  return TRUE;
+}
+
+BOOLEAN
+MyDeviceIoControl(
+    HANDLE h,
+    DWORD  dwIoControlCode,
+    PVOID  lpInBuffer,
+    DWORD  nInBufferSize,
+    PVOID  lpOutBuffer,
+    DWORD  nOutBufferSize,
+    DWORD* lpBytesReturned,
+    PVOID  lpOverlapped
+    )
+{
+
+    NTSTATUS RC;
+    BOOLEAN DevIoCtl = TRUE;
+    IO_STATUS_BLOCK Iosb;
+
+    if ( dwIoControlCode >> 16 == FILE_DEVICE_FILE_SYSTEM ) {
+        DevIoCtl = FALSE;
+    } else {
+        DevIoCtl = TRUE;
+    }
+
+    if ( DevIoCtl ) {
+        RC = NtDeviceIoControlFile(
+                    h,
+                    NULL,
+                    NULL,             // APC routine
+                    NULL,             // APC Context
+                    &Iosb,
+                    dwIoControlCode,  // IoControlCode
+                    lpInBuffer,       // Buffer for data to the FS
+                    nInBufferSize,
+                    lpOutBuffer,      // OutputBuffer for data from the FS
+                    nOutBufferSize    // OutputBuffer Length
+                    );
+    } else {
+        RC = NtFsControlFile(
+                    h,
+                    NULL,
+                    NULL,             // APC routine
+                    NULL,             // APC Context
+                    &Iosb,
+                    dwIoControlCode,  // IoControlCode
+                    lpInBuffer,       // Buffer for data to the FS
+                    nInBufferSize,
+                    lpOutBuffer,      // OutputBuffer for data from the FS
+                    nOutBufferSize    // OutputBuffer Length
+                    );
+    }
+
+    if ( RC == STATUS_PENDING) {
+        // Operation must complete before return & Iosb destroyed
+        RC = NtWaitForSingleObject( h, FALSE, NULL );
+        if ( NT_SUCCESS(RC)) {
+            RC = Iosb.Status;
+        }
+    }
+
+    if ( NT_SUCCESS(RC) ) {
+        *lpBytesReturned = Iosb.Information;
+        return TRUE;
+    } else {
+        // handle warning value STATUS_BUFFER_OVERFLOW somewhat correctly
+        if ( !NT_ERROR(RC) ) {
+            *lpBytesReturned = Iosb.Information;
+        }
+        return FALSE;
+    }
+}
+
+VOID
+Sleep(
+    ULONG t
+    )
+{
+    LARGE_INTEGER delay = {0,0};
+    delay.QuadPart = -10I64*1000*t;
+    NtDelayExecution(FALSE, &delay);
+}
+
+HANDLE hGlobalHeap = NULL;
+
+extern "C"
+PVOID
+MyGlobalAlloc(
+    ULONG Size
+    )
+{
+    if(!hGlobalHeap) {
+        // Initialize some heap
+        hGlobalHeap = RtlCreateHeap( HEAP_GROWABLE,    // Flags
+                                         NULL,              // HeapBase
+                                         0,                 // ReserveSize
+                                         0,                 // CommitSize
+                                         NULL,              // Lock
+                                         NULL );            // Parameters
+        if(!hGlobalHeap || hGlobalHeap == (HANDLE)(-1)) {
+            hGlobalHeap = NULL;
+            return NULL;
+        }
+    }
+    return RtlAllocateHeap( hGlobalHeap, 0, Size );
+}
+
+extern "C"
+VOID
+MyGlobalFree(
+    PVOID Addr
+    )
+{
+    if(!hGlobalHeap) {
+//        BrutePoint();
+        return;
+    }
+    RtlFreeHeap( hGlobalHeap, 0, Addr );
+    return;
+}
+
+CHAR dbg_print_tmp_buff[2048];
+WCHAR dbg_stringBuffer[2048];
+
+BOOLEAN was_enter = TRUE;
+
+extern "C"
+VOID
+PrintNtConsole(
+    PCHAR DebugMessage,
+    ...
+    )
+{
+    int len;
+    UNICODE_STRING msgBuff;
+    va_list ap;
+    va_start(ap, DebugMessage);
+
+    if(was_enter) {
+        strcpy(&dbg_print_tmp_buff[0], NT_DBG_PREFIX);
+        len = _vsnprintf(&dbg_print_tmp_buff[sizeof(NT_DBG_PREFIX)-1], 2047-sizeof(NT_DBG_PREFIX), DebugMessage, ap);
+    } else {
+        len = _vsnprintf(&dbg_print_tmp_buff[0], 2047, DebugMessage, ap);
+    }
+    dbg_print_tmp_buff[2047] = 0;
+    if(len > 0 &&
+       (dbg_print_tmp_buff[len-1] == '\n' ||
+        dbg_print_tmp_buff[len-1] == '\r') ) {
+        was_enter = TRUE;
+    } else {
+        was_enter = FALSE;
+    }
+
+    len = swprintf( dbg_stringBuffer, L"%S", dbg_print_tmp_buff );
+    msgBuff.Buffer = dbg_stringBuffer;
+    msgBuff.Length = len * sizeof(WCHAR);
+    msgBuff.MaximumLength = msgBuff.Length + sizeof(WCHAR);
+    NtDisplayString( &msgBuff );
+
+    va_end(ap);
+
+} // end PrintNtConsole()
+
+extern "C"
+NTSTATUS
+EnvFileOpenW(
+    PWCHAR Name,
+    HANDLE* ph
+    )
+{
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK   IoStatus;
+    NTSTATUS Status;
+    UNICODE_STRING fName;
+
+    RtlInitUnicodeString(&fName, Name);
+
+    InitializeObjectAttributes(&ObjectAttributes, &fName, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+    Status = NtCreateFile(ph,
+                             GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
+                             &ObjectAttributes,
+                             &IoStatus,
+                             NULL,
+                             FILE_ATTRIBUTE_NORMAL,
+                             FILE_SHARE_READ | FILE_SHARE_WRITE,
+                             FILE_OPEN,
+                             FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED /*| FILE_WRITE_THROUGH*/,
+                             NULL,
+                             0);
+
+    return Status;
+} // end EnvFileOpenW()
+
+extern "C"
+NTSTATUS
+EnvFileOpenA(
+    PCHAR Name,
+    HANDLE* ph
+    )
+{
+    ULONG len;
+    PWCHAR NameW;
+    NTSTATUS Status;
+
+    len = strlen(Name);
+
+    NameW = (PWCHAR)MyAllocatePool__(NonPagedPool, (len+1)*sizeof(WCHAR));
+    if(!NameW)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    swprintf(NameW, L"%S", Name);
+
+    Status = EnvFileOpenW(NameW, ph);
+
+    MyFreePool__(NameW);
+
+    return Status;
+} // end EnvFileOpenA()
+
+extern "C"
+NTSTATUS
+EnvFileClose(
+    HANDLE hFile
+    )
+{
+    return NtClose(hFile);
+} // end EnvFileClose()
+
+extern "C"
+NTSTATUS
+EnvFileGetSizeByHandle(
+    HANDLE hFile,
+    PLONGLONG lpFileSize
+    )
+{
+    NTSTATUS Status;
+    IO_STATUS_BLOCK IoStatusBlock;
+    FILE_STANDARD_INFORMATION StandardInfo;
+
+    Status = NtQueryInformationFile(
+                hFile,
+                &IoStatusBlock,
+                &StandardInfo,
+                sizeof(StandardInfo),
+                FileStandardInformation
+                );
+    if (NT_SUCCESS(Status)) {
+        *lpFileSize = StandardInfo.EndOfFile.QuadPart;
+    }
+    return Status;
+} // end EnvFileGetSizeByHandle()
+
+extern "C"
+NTSTATUS
+EnvFileGetSizeA(
+    PCHAR Name,
+    PLONGLONG lpFileSize
+    )
+{
+    NTSTATUS Status;
+    HANDLE hFile;
+
+    (*lpFileSize) = -1I64;
+
+    Status = EnvFileOpenA(Name, &hFile);
+
+    if(!NT_SUCCESS(Status))
+        return Status;
+
+    Status = EnvFileGetSizeByHandle(hFile, lpFileSize);
+
+    NtClose(hFile);
+
+    return Status;
+} // end EnvFileGetSizeA()
+
+extern "C"
+NTSTATUS
+EnvFileGetSizeW(
+    PWCHAR Name,
+    PLONGLONG lpFileSize
+    )
+{
+    NTSTATUS Status;
+    HANDLE hFile;
+
+    (*lpFileSize) = -1I64;
+
+    Status = EnvFileOpenW(Name, &hFile);
+
+    if(!NT_SUCCESS(Status))
+        return Status;
+
+    Status = EnvFileGetSizeByHandle(hFile, lpFileSize);
+
+    NtClose(hFile);
+
+    return Status;
+} // end EnvFileGetSizeW()
+
+extern "C"
+BOOLEAN
+EnvFileExistsA(PCHAR Name) {
+    LONGLONG Size;
+    EnvFileGetSizeA(Name, &Size);
+    return Size != -1;
+}
+
+extern "C"
+BOOLEAN
+EnvFileExistsW(PWCHAR Name) {
+    LONGLONG Size;
+    EnvFileGetSizeW(Name, &Size);
+    return Size != -1;
+}
+
+extern "C"
+NTSTATUS
+EnvFileWrite(
+    HANDLE h,
+    PVOID ioBuffer,
+    ULONG Length,
+    PULONG bytesWritten
+    )
+{
+    IO_STATUS_BLOCK   IoStatus;
+    NTSTATUS Status;
+
+    Status = NtWriteFile(
+                      h,
+                      NULL,               // Event
+                      NULL,               // ApcRoutine
+                      NULL,               // ApcContext
+                      &IoStatus,
+                      ioBuffer,
+                      Length,
+                      NULL,               // ByteOffset
+                      NULL                // Key
+                      );
+    (*bytesWritten) = IoStatus.Information;
+
+    return Status;
+} // end EnvFileWrite()
+
+extern "C"
+NTSTATUS
+EnvFileRead(
+    HANDLE h,
+    PVOID ioBuffer,
+    ULONG Length,
+    PULONG bytesRead
+    )
+{
+    IO_STATUS_BLOCK   IoStatus;
+    NTSTATUS Status;
+
+    Status = NtReadFile(
+                      h,
+                      NULL,               // Event
+                      NULL,               // ApcRoutine
+                      NULL,               // ApcContext
+                      &IoStatus,
+                      ioBuffer,
+                      Length,
+                      NULL,               // ByteOffset
+                      NULL                // Key
+                      );
+    (*bytesRead) = IoStatus.Information;
+
+    return Status;
+} // end EnvFileRead()
+
+extern "C"
+NTSTATUS
+EnvFileSetPointer(
+    HANDLE hFile,
+    LONGLONG lDistanceToMove,
+    LONGLONG* lResultPointer,
+    DWORD dwMoveMethod
+    )
+{
+    NTSTATUS Status;
+    IO_STATUS_BLOCK IoStatus;
+    FILE_POSITION_INFORMATION CurrentPosition;
+    FILE_STANDARD_INFORMATION FileInfo;
+
+    switch (dwMoveMethod) {
+        case ENV_FILE_BEGIN :
+            CurrentPosition.CurrentByteOffset.QuadPart = lDistanceToMove;
+                break;
+
+        case ENV_FILE_CURRENT :
+
+            // Get the current position of the file pointer
+            Status = NtQueryInformationFile(
+                        hFile,
+                        &IoStatus,
+                        &CurrentPosition,
+                        sizeof(CurrentPosition),
+                        FilePositionInformation
+                        );
+            if(!NT_SUCCESS(Status)) {
+                return Status;
+            }
+            CurrentPosition.CurrentByteOffset.QuadPart += lDistanceToMove;
+            break;
+
+        case ENV_FILE_END :
+            Status = NtQueryInformationFile(
+                        hFile,
+                        &IoStatus,
+                        &FileInfo,
+                        sizeof(FileInfo),
+                        FileStandardInformation
+                        );
+            if (!NT_SUCCESS(Status)) {
+                return Status;
+            }
+            CurrentPosition.CurrentByteOffset.QuadPart =
+                                FileInfo.EndOfFile.QuadPart + lDistanceToMove;
+            break;
+
+        default:
+            return STATUS_INVALID_PARAMETER;
+        }
+
+    if ( CurrentPosition.CurrentByteOffset.QuadPart < 0 ) {
+        return Status;
+    }
+
+    Status = NtSetInformationFile(
+                hFile,
+                &IoStatus,
+                &CurrentPosition,
+                sizeof(CurrentPosition),
+                FilePositionInformation
+                );
+
+    if(!NT_SUCCESS(Status)) {
+        return Status;
+    }
+    if(lResultPointer) {
+        *lResultPointer = CurrentPosition.CurrentByteOffset.QuadPart;
+    }
+    return STATUS_SUCCESS;
+} // end EnvFileSetPointer()
+
+NTSTATUS EnvFileDeleteW(PWCHAR Name) {
+
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK   IoStatus;
+    NTSTATUS Status;
+    UNICODE_STRING fName;
+    HANDLE Handle;
+    FILE_DISPOSITION_INFORMATION Disposition;
+
+    RtlInitUnicodeString(&fName, Name);
+
+    InitializeObjectAttributes(&ObjectAttributes, &fName, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+    Status = NtOpenFile(
+                 &Handle,
+                 (ACCESS_MASK)DELETE,
+                 &ObjectAttributes,
+                 &IoStatus,
+                 FILE_SHARE_DELETE |
+                 FILE_SHARE_READ |
+                 FILE_SHARE_WRITE,
+                 FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT
+             );
+    
+    
+    if ( !NT_SUCCESS(Status) ) {
+        return Status;
+    }
+
+    Disposition.DeleteFile = TRUE;
+
+    Status = NtSetInformationFile(
+                 Handle,
+                 &IoStatus,
+                 &Disposition,
+                 sizeof(Disposition),
+                 FileDispositionInformation
+             );
+
+    NtClose(Handle);
+
+    return Status;
+}
+#endif //NT_NATIVE_MODE
diff --git a/reactos/drivers/filesystems/udfs/Include/env_spec_nt.h b/reactos/drivers/filesystems/udfs/Include/env_spec_nt.h
new file mode 100644 (file)
index 0000000..c820f9d
--- /dev/null
@@ -0,0 +1,177 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifndef __ENV_SPEC_NT_NATIVE__H__
+#define __ENV_SPEC_NT_NATIVE__H__
+
+#ifdef NT_NATIVE_MODE
+
+#include "zw_2_nt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif //__cplusplus
+
+#ifndef MAX_PATH
+#define MAX_PATH   260
+#endif //MAX_PATH
+
+BOOLEAN
+GetOsVersion(
+    PULONG MajorVersion OPTIONAL,
+    PULONG MinorVersion OPTIONAL,
+    PULONG BuildNumber OPTIONAL,
+    PUNICODE_STRING CSDVersion OPTIONAL
+    );
+
+#define PsGetVersion(a,b,c,d)  GetOsVersion(a,b,c,d)
+
+#define InterlockedIncrement(addr) \
+    ((*addr)++)
+#define InterlockedDecrement(addr) \
+    ((*addr)--)
+int
+__inline
+InterlockedExchangeAdd(PLONG addr, LONG i) {
+    LONG Old = (*addr);
+    (*addr) += i;
+    return Old;
+}
+
+#define DeviceIoControl(h, ctlc, ib, is, ob, os, r, ov)  MyDeviceIoControl(h, ctlc, ib, is, ob, os, r, ov)  
+
+BOOLEAN
+MyDeviceIoControl(
+    HANDLE hDevice,
+    DWORD  dwIoControlCode,
+    PVOID  lpInBuffer,
+    DWORD  nInBufferSize,
+    PVOID  lpOutBuffer,
+    DWORD  nOutBufferSize,
+    DWORD* lpBytesReturned,
+    PVOID  lpOverlapped
+    );
+
+#define OemToCharW(ansi_s, uni_s)    (swprintf(uni_s, L"%S", ansi_s))
+#define MultiByteToWideChar(cp, f, ansi_s, a_sz, uni_s, u_sz)  (swprintf(uni_s, L"%S", ansi_s))
+
+VOID
+Sleep(
+    ULONG t
+    );
+
+#define GlobalAlloc(foo, size)  MyGlobalAlloc( size );
+#define GlobalFree(ptr)         MyGlobalFree( ptr );
+
+extern "C"
+PVOID MyGlobalAlloc(ULONG Size);
+
+extern "C"
+VOID  MyGlobalFree(PVOID Addr);
+
+#define ExitProcess(Status)    NtTerminateProcess( NtCurrentProcess(), Status );
+
+extern "C"
+VOID
+PrintNtConsole(
+    PCHAR DebugMessage,
+    ...
+    );
+
+extern "C"
+NTSTATUS
+EnvFileOpenW(
+    PWCHAR Name,
+    HANDLE* ph
+    );
+
+extern "C"
+NTSTATUS
+EnvFileOpenA(
+    PCHAR Name,
+    HANDLE* ph
+    );
+
+extern "C"
+NTSTATUS
+EnvFileClose(
+    HANDLE hFile
+    );
+
+extern "C"
+NTSTATUS
+EnvFileGetSizeByHandle(
+    HANDLE hFile,
+    PLONGLONG lpFileSize
+    );
+
+extern "C"
+NTSTATUS
+EnvFileGetSizeA(
+    PCHAR Name,
+    PLONGLONG lpFileSize
+    );
+
+extern "C"
+NTSTATUS
+EnvFileGetSizeW(
+    PWCHAR Name,
+    PLONGLONG lpFileSize
+    );
+
+extern "C"
+BOOLEAN
+EnvFileExistsA(PCHAR Name);
+
+extern "C"
+BOOLEAN
+EnvFileExistsW(PWCHAR Name);
+
+extern "C"
+NTSTATUS
+EnvFileWrite(
+    HANDLE h,
+    PVOID ioBuffer,
+    ULONG Length,
+    PULONG bytesWritten
+    );
+
+extern "C"
+NTSTATUS
+EnvFileRead(
+    HANDLE h,
+    PVOID ioBuffer,
+    ULONG Length,
+    PULONG bytesRead
+    );
+
+#define ENV_FILE_CURRENT  1
+#define ENV_FILE_END      2
+#define ENV_FILE_BEGIN    3
+
+extern "C"
+NTSTATUS
+EnvFileSetPointer(
+    HANDLE hFile,
+    LONGLONG lDistanceToMove,
+    LONGLONG* lResultPointer,
+    DWORD dwMoveMethod
+    );
+
+extern "C"
+NTSTATUS 
+EnvFileDeleteW(
+    PWCHAR fName
+    );
+
+#define PrintDbgConsole    PrintNtConsole
+
+#ifdef __cplusplus
+};
+#endif //__cplusplus
+
+#endif //NT_NATIVE_MODE
+
+#endif //__ENV_SPEC_NT_NATIVE__H__
diff --git a/reactos/drivers/filesystems/udfs/Include/env_spec_w32.cpp b/reactos/drivers/filesystems/udfs/Include/env_spec_w32.cpp
new file mode 100644 (file)
index 0000000..c24a894
--- /dev/null
@@ -0,0 +1,1149 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifndef UDF_FORMAT_MEDIA
+ULONG   LockMode       = 0;
+BOOLEAN opt_invalidate_volume = FALSE;
+#endif //UDF_FORMAT_MEDIA
+
+#ifndef CDRW_W32
+#ifndef UDF_FORMAT_MEDIA
+BOOLEAN open_as_device = FALSE;
+#endif //UDF_FORMAT_MEDIA
+#ifdef USE_SKIN_MODEL
+
+PSKIN_API SkinAPI = NULL;
+
+PSKIN_API
+SkinLoad(
+    PWCHAR path,
+    HINSTANCE hInstance,      // handle to current instance
+    HINSTANCE hPrevInstance,  // handle to previous instance
+    int nCmdShow              // show state
+    )
+{
+    HMODULE hm;
+    PSKIN_API Skin;
+    PSKIN_API (__stdcall *SkinInit) (VOID);
+
+    hm = LoadLibraryW(path);
+    if(!hm)
+        return NULL;
+    SkinInit = (PSKIN_API(__stdcall *)(void))GetProcAddress(hm, "SkinInit");
+    if(!SkinInit)
+        return NULL;
+    Skin = SkinInit();
+    if(!Skin)
+        return NULL;
+    Skin->Init(hInstance, hPrevInstance, nCmdShow);
+    return Skin;
+}
+
+
+#endif //USE_SKIN_MODEL
+
+#ifdef _BROWSE_UDF_
+#ifndef LIBUDF
+
+extern PVCB Vcb;
+
+#endif // LIBUDF
+#endif //_BROWSE_UDF_
+
+#ifdef LIBUDF
+#define _lphUdf  ((PUDF_VOL_HANDLE_I)(DeviceObject->lpContext))
+#endif //LIBUDF
+#ifdef LIBUDFFMT
+#define _lphUdf  (DeviceObject->cbio)
+#endif //LIBUDFFMT
+
+#ifndef CDRW_W32
+
+NTSTATUS
+UDFPhSendIOCTL(
+    IN ULONG IoControlCode,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PVOID InputBuffer ,
+    IN ULONG InputBufferLength,
+    OUT PVOID OutputBuffer ,
+    IN ULONG OutputBufferLength,
+    IN BOOLEAN OverrideVerify,
+    OUT PVOID Iosb OPTIONAL
+    )
+{
+    ULONG real_read;
+#if !defined(LIBUDF) && !defined(LIBUDFFMT)
+    ULONG ret;
+
+    ULONG RC = DeviceIoControl(DeviceObject->h,IoControlCode,
+                                InputBuffer,InputBufferLength,
+                                OutputBuffer,OutputBufferLength,
+                                &real_read,NULL);
+
+    if (!RC) {
+        ret = GetLastError();
+    }
+    return RC ? 1 : -1;
+
+#else // LIBUDF
+
+    ULONG RC = _lphUdf->lpIOCtlFunc(_lphUdf->lpParameter,IoControlCode,
+                                InputBuffer,InputBufferLength,
+                                OutputBuffer,OutputBufferLength,
+                                &real_read);
+
+    return RC;
+
+#endif // LIBUDF
+
+} // end UDFPhSendIOCTL()
+
+
+NTSTATUS
+UDFPhReadSynchronous(
+    PDEVICE_OBJECT DeviceObject,  // the physical device object
+    PVOID          Buffer,
+    ULONG          Length,
+    LONGLONG       Offset,
+    PULONG         ReadBytes,
+    ULONG          Flags
+    )
+{
+
+#if !defined(LIBUDF) && !defined(LIBUDFFMT)
+
+    NTSTATUS    RC;
+//    KdPrint(("UDFPhRead: Length: %x Lba: %lx\n",Length>>0xb,Offset>>0xb));
+    LONG HiOffs = (ULONG)(Offset >> 32);
+
+    RC = SetFilePointer(DeviceObject->h,(ULONG)Offset,&HiOffs,FILE_BEGIN);
+    if(RC == INVALID_SET_FILE_POINTER) {
+        if(GetLastError() != NO_ERROR) {
+            KdPrint(("UDFPhReadSynchronous: error %x\n", GetLastError()));
+            return STATUS_END_OF_FILE;
+        }
+    }
+    RC = ReadFile(DeviceObject->h,Buffer,Length,ReadBytes,NULL);
+    if(NT_SUCCESS(RC) &&
+        (!(*ReadBytes))) {
+        RC = GetLastError();
+        return STATUS_END_OF_FILE;
+    }
+    return STATUS_SUCCESS;
+
+#else // LIBUDF
+
+    return _lphUdf->lpReadFunc(_lphUdf->lpParameter,
+                              Buffer,
+                              Length,
+                              Offset,
+                              ReadBytes);
+
+#endif //defined LIBUDF || defined LIBUDFFMT
+
+} // end UDFPhReadSynchronous()
+
+
+NTSTATUS
+UDFPhWriteSynchronous(
+    PDEVICE_OBJECT     DeviceObject,  // the physical device object
+    PVOID          Buffer,
+    ULONG          Length,
+    LONGLONG       Offset,
+    PULONG         WrittenBytes,
+    ULONG          Flags
+    )
+{
+#if !defined(LIBUDF) && !defined(LIBUDFFMT)
+
+    NTSTATUS    RC = STATUS_SUCCESS;
+    LONG HiOffs = (ULONG)(Offset >> 32);
+    PVOID Buffer2 = NULL;
+    PVOID Buffer3 = NULL;
+
+    RC = SetFilePointer(DeviceObject->h,(ULONG)Offset,&HiOffs,FILE_BEGIN);
+    if(RC == INVALID_SET_FILE_POINTER) {
+        if(GetLastError() != NO_ERROR) {
+            KdPrint(("UDFPhWriteSynchronous: error %x\n", GetLastError()));
+            return STATUS_END_OF_FILE;
+        }
+    }
+
+    Buffer2 = ExAllocatePool(NonPagedPool, Length+0x10000);
+    Buffer3 = (PVOID)( ((ULONG)Buffer2 + 0xffff) & ~0xffff);
+    RtlCopyMemory(Buffer3, Buffer, Length);
+
+    RC = WriteFile(DeviceObject->h,Buffer3,Length,WrittenBytes,NULL);
+    if(!RC ||
+        !(*WrittenBytes)) {
+        RC = GetLastError();
+        KdPrint(("UDFPhWriteSynchronous: EOF, error %x\n", RC));
+        RC = STATUS_END_OF_FILE;
+    } else {
+        RC = STATUS_SUCCESS;
+    }
+
+    if(Buffer2) ExFreePool(Buffer2);
+
+    return RC;
+
+#else // LIBUDF
+
+    return _lphUdf->lpWriteFunc(_lphUdf->lpParameter,
+                              Buffer,
+                              Length,
+                              Offset,
+                              WrittenBytes);
+
+#endif // LIBUDF
+
+} // end UDFPhWriteSynchronous()
+
+#if 0
+NTSTATUS
+UDFPhWriteVerifySynchronous(
+    PDEVICE_OBJECT  DeviceObject,   // the physical device object
+    PVOID           Buffer,
+    ULONG           Length,
+    LONGLONG        Offset,
+    PULONG          WrittenBytes,
+    ULONG           Flags
+    )
+{
+    NTSTATUS RC;
+    PUCHAR v_buff = NULL;
+    ULONG ReadBytes;
+
+    RC = UDFPhWriteSynchronous(DeviceObject, Buffer, Length, Offset, WrittenBytes, 0);
+    if(!Verify)
+        return RC;
+    v_buff = (PUCHAR)DbgAllocatePool(NonPagedPool, Length);
+    if(!v_buff)
+        return RC;
+
+    RC = UDFPhSendIOCTL( IOCTL_CDRW_SYNC_CACHE, DeviceObject,
+                    NULL,0, NULL,0, FALSE, NULL);
+
+    RC = UDFPhReadSynchronous(DeviceObject, v_buff, Length, Offset, &ReadBytes, 0);
+    if(!NT_SUCCESS(RC)) {
+        BrutePoint();
+        DbgFreePool(v_buff);
+        return RC;
+    }
+    if(RtlCompareMemory(v_buff, Buffer, ReadBytes) == Length) {
+        DbgFreePool(v_buff);
+        return RC;
+    }
+    BrutePoint();
+    DbgFreePool(v_buff);
+    return STATUS_LOST_WRITEBEHIND_DATA;
+} // end UDFPhWriteVerifySynchronous()
+#endif
+
+VOID
+set_image_size(
+    HANDLE h,
+//    ULONG LBA)
+    int64  len)
+{
+    LONG offh = (ULONG)(len >> 32);
+                        //( (LONGLONG)LBA >> (32-Vcb->BlockSizeBits) );
+
+    SetFilePointer((HANDLE)h, (ULONG)(len /*(LBA << Vcb->BlockSizeBits)*/ ), &offh, FILE_BEGIN);
+    SetEndOfFile(h);
+    offh = 0;
+    SetFilePointer((HANDLE)h, 0, &offh, FILE_BEGIN);
+} // end set_image_size()
+
+int64
+get_file_size(
+    HANDLE h
+    )
+{
+    LONG hsz = 0;
+    LONG lsz;
+
+    lsz = SetFilePointer(h, 0, &hsz, FILE_END);
+    return (((int64)hsz) << 32) | lsz;
+} // end get_file_size()
+
+int64
+set_file_pointer(
+    HANDLE h,
+    int64 sz
+    )
+{
+    ULONG hsz = (ULONG)(sz >> 32);
+    ULONG lsz = (ULONG)sz;
+
+    lsz = SetFilePointer(h, lsz, (PLONG)&hsz, FILE_BEGIN);
+    return (((int64)hsz) << 32) | lsz;
+} // end set_file_pointer()
+
+#endif //CDRW_W32
+
+#ifndef LIBUDF
+
+#ifndef UDF_FORMAT_MEDIA
+
+ULONG
+write(
+    PVCB Vcb,
+    HANDLE h,
+    PCHAR buff,
+    ULONG len)
+{
+    ULONG written;
+    LONG offh = 0;
+    ULONG offl = SetFilePointer((HANDLE)h, 0, &offh, FILE_CURRENT);
+//    ULONG Lba = (ULONG)((((LONGLONG)offh << 32) + offl) >> Vcb->BlockSizeBits);
+
+    UDFWriteData(Vcb, FALSE, (((LONGLONG)offh)<<32)+offl, len, FALSE, buff, &written);
+
+    SetFilePointer((HANDLE)h, offl, &offh, FILE_BEGIN);
+    offh = 0;
+    SetFilePointer((HANDLE)h, written, &offh, FILE_CURRENT);
+
+    return written;
+} // end write()
+#endif //UDF_FORMAT_MEDIA
+
+#endif // LIBUDF
+
+#endif //CDRW_W32
+
+#ifdef NT_NATIVE_MODE
+
+BOOL
+Privilege(
+    LPTSTR pszPrivilege, 
+    BOOL bEnable
+    )
+{
+#ifndef NT_NATIVE_MODE
+    HANDLE           hToken;
+    TOKEN_PRIVILEGES tp;
+
+    // obtain the token, first check the thread and then the process
+    if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TRUE, &hToken)) {
+        if (GetLastError() == ERROR_NO_TOKEN) {
+            if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
+                return FALSE;
+            }
+        } else {
+            return FALSE;
+        }
+    }
+
+    // get the luid for the privilege
+    if (!LookupPrivilegeValue(NULL, pszPrivilege, &tp.Privileges[0].Luid)) {
+        CloseHandle(hToken);
+        return FALSE;
+    }
+
+    tp.PrivilegeCount = 1;
+
+    if (bEnable)
+        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+    else
+        tp.Privileges[0].Attributes = 0;
+
+    // enable or disable the privilege
+    if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0)) {
+        CloseHandle(hToken);
+        return FALSE;
+    }
+
+    if (!CloseHandle(hToken))
+        return FALSE;
+
+#endif //NT_NATIVE_MODE
+
+    return TRUE;
+
+} // end Privilege()
+#endif //NT_NATIVE_MODE
+
+#ifndef LIBUDF
+
+extern "C"
+ULONG
+MyLockVolume(
+    HANDLE h,
+    ULONG* pLockMode // OUT
+    )
+{
+    ULONG RC;
+    ULONG returned;
+
+    (*pLockMode) = -1;
+#ifndef CDRW_W32
+    RC = DeviceIoControl(h,IOCTL_UDF_LOCK_VOLUME_BY_PID,NULL,0,NULL,0,&returned,NULL);
+    if(RC) {
+        (*pLockMode) = IOCTL_UDF_LOCK_VOLUME_BY_PID;
+        return STATUS_SUCCESS;
+    }
+#endif //CDRW_W32
+
+    RC = DeviceIoControl(h,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&returned,NULL);
+    if(RC) {
+        (*pLockMode) = FSCTL_LOCK_VOLUME;
+        return STATUS_SUCCESS;
+    }
+    return STATUS_UNSUCCESSFUL;
+} // MyLockVolume()
+
+extern "C"
+ULONG
+MyUnlockVolume(
+    HANDLE h,
+    ULONG* pLockMode // IN
+    )
+{
+    ULONG returned;
+
+#ifndef CDRW_W32
+    if((*pLockMode) == IOCTL_UDF_LOCK_VOLUME_BY_PID) {
+        return DeviceIoControl(h,IOCTL_UDF_UNLOCK_VOLUME_BY_PID,NULL,0,NULL,0,&returned,NULL);
+    }
+#endif //CDRW_W32
+
+    return DeviceIoControl(h,FSCTL_UNLOCK_VOLUME,NULL,0,NULL,0,&returned,NULL);
+
+} // MyUnlockVolume()
+
+void
+my_retrieve_vol_type(
+#ifndef CDRW_W32
+    PVCB Vcb,
+#endif
+    PWCHAR fn
+    )
+{
+#ifndef CDRW_W32
+    if(wcslen(fn) == 2 && fn[1] == ':') {
+        ULONG DevType = GetDriveTypeW(fn);
+        KdPrint(("  DevType %x\n", DevType));
+        switch(DevType) {
+        case DRIVE_CDROM:
+            Vcb->PhDeviceType = FILE_DEVICE_CD_ROM;
+            break;
+        default:
+            Vcb->PhDeviceType = FILE_DEVICE_DISK;
+            break;
+        }
+    }
+    if(wcslen(fn) == 2 && fn[1] == ';') {
+        UserPrint(("Warrning: File name is similar to drive letter.\n"
+                   "  Don't you type semicolon ';' instead of colon ':' ?\n"));
+    }
+#endif //CDRW_W32
+} // end my_retrieve_vol_type()
+
+
+#ifdef NT_NATIVE_MODE
+#define GetLastError()    ((ULONG)(-1))
+#endif //NT_NATIVE_MODE
+
+#define MAX_INVALIDATE_VOLUME_RETRY 8
+
+extern "C"
+HANDLE
+my_open(
+#ifndef CDRW_W32
+    PVCB Vcb,
+#endif
+    PWCHAR fn
+    )
+{
+    HANDLE h/*, h2*/;
+    WCHAR deviceNameBuffer[0x200];
+    WCHAR FSNameBuffer[0x200];
+//    CCHAR RealDeviceName[0x200];
+//    WCHAR DeviceName[MAX_PATH+1];
+    ULONG RC;
+    ULONG retry;
+    ULONG i;
+    BOOLEAN CantLock = FALSE;
+    PULONG pLockMode;
+#ifdef NT_NATIVE_MODE
+    IO_STATUS_BLOCK ioStatus;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING uniFilename;
+#endif //NT_NATIVE_MODE
+    ULONG returned;
+
+#ifndef CDRW_W32
+#ifdef UDF_FORMAT_MEDIA
+    PUDFFmtState fms = Vcb->fms;
+    fms->
+#endif
+        open_as_device = TRUE;
+#endif //CDRW_W32
+
+    pLockMode = &
+#ifdef UDF_FORMAT_MEDIA
+        fms->
+#endif
+        LockMode;
+
+    // make several retries to workaround smart applications,
+    // those attempts to work with volume immediately after arrival
+    retry = 1 +
+#ifdef UDF_FORMAT_MEDIA
+        fms->
+#endif
+            opt_invalidate_volume ? 0 : MAX_INVALIDATE_VOLUME_RETRY;
+
+#ifndef NT_NATIVE_MODE
+    swprintf(deviceNameBuffer, L"%ws\\", fn);
+    KdPrint(("my_open: %S\n", fn));
+    i = sizeof(FSNameBuffer)/sizeof(FSNameBuffer[0]);
+    if(GetVolumeInformationW(deviceNameBuffer, NULL, 0, 
+        &returned, &returned, &returned, FSNameBuffer, i)) {
+        KdPrint(("my_open: FS: %S\n", FSNameBuffer));
+        if(!wcscmp(FSNameBuffer, L"Unknown")) {
+            retry++;
+        }
+    } else {
+        KdPrint(("my_open: FS: ???\n"));
+    }
+    KdPrint(("my_open: retry %d times\n", retry));
+
+#endif //NT_NATIVE_MODE
+
+    do {
+    // open as device
+#ifndef NT_NATIVE_MODE
+    swprintf(deviceNameBuffer, L"\\\\.\\%ws", fn);
+    if(wcslen(fn) == 2 && fn[1] == ';') {
+        UserPrint(("Warrning: File name is similar to drive letter.\n"
+                   "  Don't you type semicolon ';' instead of colon ':' ?\n"));
+    }
+    h = (HANDLE)(-1);
+    for(i=0; i<4; i++) {
+        if(h == ((HANDLE)-1)) {
+            h = CreateFileW(deviceNameBuffer, GENERIC_READ | GENERIC_WRITE,
+                           ((i & 1) ? 0 : FILE_SHARE_READ) | ((i & 2) ? 0 : FILE_SHARE_WRITE),
+                           NULL,
+                           OPEN_EXISTING,
+                           FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING,  NULL);
+            if(h != ((HANDLE)-1)) {
+                KdPrint(("  opened i=%x\n", i));
+            }
+        }
+    }
+#else //NT_NATIVE_MODE
+    uniFilename.Length = swprintf(deviceNameBuffer, L"\\??\\%ws", fn);
+    uniFilename.Buffer = deviceNameBuffer;
+    uniFilename.Length *= sizeof(WCHAR);
+    uniFilename.MaximumLength = uniFilename.Length + sizeof(WCHAR);
+
+    h = (HANDLE)(-1);
+    for(i=0; i<4; i++) {
+        InitializeObjectAttributes(&ObjectAttributes, &uniFilename, OBJ_CASE_INSENSITIVE, NULL, NULL);
+        if(h == ((HANDLE)-1)) {
+            RC = NtCreateFile(&h,
+                                     GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE | FILE_READ_ATTRIBUTES,
+                                     &ObjectAttributes,
+                                     &ioStatus,
+                                     NULL,
+                                     FILE_ATTRIBUTE_NORMAL,
+                                     ((i & 1) ? 0 : FILE_SHARE_READ) | ((i & 2) ? 0 : FILE_SHARE_WRITE),
+                                     FILE_OPEN,
+                                     FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED | FILE_WRITE_THROUGH | FILE_NO_INTERMEDIATE_BUFFERING,
+                                     NULL,
+                                     0);
+            if(!NT_SUCCESS(RC)) {
+                KdPrint(("  opened i2=%x\n", i));
+                h = ((HANDLE)-1);
+            }
+        }
+    }
+#endif //NT_NATIVE_MODE
+    if(h != ((HANDLE)-1)) {
+#ifndef CDRW_W32
+#ifdef UDF_FORMAT_MEDIA
+        if(fms->opt_flush || fms->opt_probe) {
+            return h;
+        }
+#endif //UDF_FORMAT_MEDIA
+        my_retrieve_vol_type(Vcb, fn);
+#else
+        my_retrieve_vol_type(fn);
+#endif //CDRW_W32
+        if(!NT_SUCCESS(MyLockVolume(h,pLockMode))) {
+#ifndef CDRW_W32
+            if(retry < MAX_INVALIDATE_VOLUME_RETRY) {
+                retry++;
+                if(!Privilege(SE_TCB_NAME, TRUE)) {
+                    KdPrint(("SE_TCB privilege not held\n"));
+                } else
+                if(DeviceIoControl(h,FSCTL_INVALIDATE_VOLUMES,&h,sizeof(h),NULL,0,&returned,NULL) ) {
+                    KdPrint(("  FSCTL_INVALIDATE_VOLUMES ok, status %x\n", GetLastError()));
+                    CloseHandle(h);
+                    continue;
+                } else {
+//#ifndef CDRW_W32
+                    KdPrint(("  FSCTL_INVALIDATE_VOLUMES failed, error %x\n", GetLastError()));
+                    RC = GetLastError();
+                    if(DeviceIoControl(h,IOCTL_UDF_INVALIDATE_VOLUMES,&h,sizeof(h),NULL,0,&returned,NULL) ) {
+                        KdPrint(("  IOCTL_UDF_INVALIDATE_VOLUMES ok, status %x\n", GetLastError()));
+                        CloseHandle(h);
+                        continue;
+                    }
+                    KdPrint(("  IOCTL_UDF_INVALIDATE_VOLUMES, error %x\n", GetLastError()));
+//#endif //CDRW_W32
+                }
+                UserPrint(("can't lock volume, retry\n"));
+                CloseHandle(h);
+                continue;
+            }
+#endif //CDRW_W32
+            UserPrint(("can't lock volume\n"));
+#ifndef NT_NATIVE_MODE
+            // In native mode the volume can be not mounted yet !!!
+            CantLock = TRUE;
+            CloseHandle(h);
+            h = NULL;
+            goto try_as_file;
+#endif //NT_NATIVE_MODE
+        }
+//#ifndef CDRW_W32
+        if(!DeviceIoControl(h,FSCTL_ALLOW_EXTENDED_DASD_IO,NULL,0,NULL,0,&returned,NULL)) {
+            KdPrint(("Warning: can't allow extended DASD i/o\n"));
+        }
+//#endif //CDRW_W32
+
+        KdPrint(("  opened, h=%x\n", h));
+        return h;
+    }
+    RC = GetLastError();
+
+#ifndef NT_NATIVE_MODE
+    h = CreateFileW(deviceNameBuffer, GENERIC_READ,
+                   FILE_SHARE_READ,
+                   NULL,
+                   OPEN_EXISTING,
+                   FILE_ATTRIBUTE_NORMAL,  NULL);
+#else //NT_NATIVE_MODE
+    RC = NtCreateFile(&h,
+                             GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES,
+                             &ObjectAttributes,
+                             &ioStatus,
+                             NULL,
+                             FILE_ATTRIBUTE_NORMAL,
+                             FILE_SHARE_READ,
+                             FILE_OPEN,
+                             FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED | FILE_WRITE_THROUGH,
+                             NULL,
+                             0);
+    if(!NT_SUCCESS(RC)) {
+        h = ((HANDLE)-1);
+    }
+#endif //NT_NATIVE_MODE
+    if(h != ((HANDLE)-1)) {
+
+        KdPrint(("  opened R/O, h=%x\n", h));
+#ifndef CDRW_W32
+        my_retrieve_vol_type(Vcb, fn);
+#else
+        my_retrieve_vol_type(fn);
+#endif
+
+        UserPrint(("read-only open\n"));
+        if(!NT_SUCCESS(MyLockVolume(h,pLockMode))) {
+#ifndef CDRW_W32
+            if(retry < MAX_INVALIDATE_VOLUME_RETRY) {
+                retry++;
+                if(!Privilege(SE_TCB_NAME, TRUE)) {
+                    KdPrint(("SE_TCB privilege not held\n"));
+                } else
+                if(DeviceIoControl(h,FSCTL_INVALIDATE_VOLUMES,&h,sizeof(h),NULL,0,&returned,NULL) ) {
+                    CloseHandle(h);
+                    continue;
+                }
+                UserPrint(("can't lock read-only volumem retry"));
+                CloseHandle(h);
+                continue;
+            }
+#endif //CDRW_W32
+            UserPrint(("can't lock read-only volume"));
+#ifndef NT_NATIVE_MODE
+            CantLock = TRUE;
+            CloseHandle(h);
+            h = NULL;
+            goto try_as_file;
+#endif //NT_NATIVE_MODE
+        }
+//        write_cdfs = TRUE;
+//        DeviceIoControl(h,FSCTL_DISMOUNT_VOLUME,NULL,0,NULL,0,&returned,NULL);
+        return h;
+    }
+#ifndef NT_NATIVE_MODE
+try_as_file:
+#endif //NT_NATIVE_MODE
+
+#ifndef CDRW_W32
+#ifdef UDF_FORMAT_MEDIA
+    fms->
+#endif
+    open_as_device = FALSE;
+    // open as plain file
+    Vcb->PhDeviceType = FILE_DEVICE_DISK;
+#endif //CDRW_W32
+
+    UserPrint(("try image file\n"));
+#ifndef NT_NATIVE_MODE
+    h = CreateFileW(fn, GENERIC_READ | GENERIC_WRITE,
+                   FILE_SHARE_READ,
+                   NULL,
+                   CREATE_ALWAYS,
+                   FILE_ATTRIBUTE_NORMAL,  NULL);
+#else //NT_NATIVE_MODE
+    RC = NtCreateFile(&h,
+                             GENERIC_READ | SYNCHRONIZE,
+                             &ObjectAttributes,
+                             &ioStatus,
+                             NULL,
+                             FILE_ATTRIBUTE_NORMAL,
+                             FILE_SHARE_READ,
+                             FILE_OPEN,
+                             FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED | FILE_WRITE_THROUGH,
+                             NULL,
+                             0);
+    if(!NT_SUCCESS(RC)) {
+        h = ((HANDLE)-1);
+    }
+#endif //NT_NATIVE_MODE
+    if(h == ((HANDLE)-1)) {
+
+        RC = GetLastError();
+        if(CantLock) {
+#ifndef CDRW_W32
+            my_exit(
+#ifdef UDF_FORMAT_MEDIA
+                fms,
+#endif
+                MKUDF_CANT_LOCK_VOL);
+#else
+            return NULL;
+#endif //CDRW_W32
+        }
+#ifndef CDRW_W32
+        UserPrint(("error opening device or image file"));
+        my_exit(
+#ifdef UDF_FORMAT_MEDIA
+                fms,
+#endif
+            MKUDF_CANT_OPEN_FILE);
+#else
+        return NULL;
+#endif //CDRW_W32
+    }
+    KdPrint(("  opened as file, h=%x\n", h));
+    break;
+
+    } while(TRUE);
+    return h;
+} // end my_open()
+
+#endif //LIBUDF
+
+#ifndef CDRW_W32
+
+uint64
+udf_lseek64(
+    HANDLE fd,
+    uint64 offset,
+    int whence)
+{
+    LONG offh = (ULONG)(offset>>32);
+    LONG offl;
+    offl = SetFilePointer(fd, (ULONG)offset, &offh, whence);
+    if(offl == -1 && offh == -1) {
+        return -1;
+    }
+    return (((uint64)offh) << 32) | (uint64)offl;
+} // end udf_lseek64()
+
+#ifdef LIBUDFFMT
+BOOLEAN
+udf_get_sizes(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN ULONG* blocks
+    )
+{
+    ULONG bs;
+    int64 sz;
+    ULONG RC;
+
+    RC = _lphUdf->lpGetSizeFunc(_lphUdf->lpParameter, &sz, &bs);
+
+    (*blocks) = (ULONG)(sz/bs);
+
+    return(OS_SUCCESS(RC));
+}
+#endif //LIBUDFFMT
+    
+#include "string_lib.cpp"
+
+#ifdef _BROWSE_UDF_
+#ifndef LIBUDF
+
+ULONG
+UDFGetDevType(
+    PDEVICE_OBJECT DeviceObject
+    )
+{
+    if(DeviceObject && DeviceObject == Vcb->TargetDeviceObject) {
+        return Vcb->PhDeviceType;
+    }
+    return FILE_DEVICE_DISK;
+} // end UDFGetDevType()
+
+#else  // LIBUDF
+
+ULONG
+UDFGetDevType(
+    PDEVICE_OBJECT DeviceObject
+    )
+{
+#define lphUdf  ((PUDF_VOL_HANDLE_I)(DeviceObject->lpContext))
+    return lphUdf->bHddDevice ? FILE_DEVICE_DISK : FILE_DEVICE_CD_ROM;
+#undef lphUdf
+} // end UDFGetDevType()
+
+#endif // LIBUDF
+
+#endif //_BROWSE_UDF_
+
+#endif //CDRW_W32
+
+#ifndef NT_NATIVE_MODE
+
+#ifdef PRINT_DBG_CONSOLE
+CHAR dbg_print_tmp_buff[2048];
+
+BOOLEAN was_enter = TRUE;
+
+extern "C"
+VOID
+PrintDbgConsole(
+    PCHAR DebugMessage,
+    ...
+    )
+{
+    int len;
+    va_list ap;
+    va_start(ap, DebugMessage);
+
+    if(was_enter) {
+        strcpy(&dbg_print_tmp_buff[0], JS_DBG_PREFIX);
+        len = _vsnprintf(&dbg_print_tmp_buff[sizeof(JS_DBG_PREFIX)-1], 2047-sizeof(JS_DBG_PREFIX), DebugMessage, ap);
+    } else {
+        len = _vsnprintf(&dbg_print_tmp_buff[0], 2047, DebugMessage, ap);
+    }
+    dbg_print_tmp_buff[2047] = 0;
+    if(len > 0 &&
+       (dbg_print_tmp_buff[len-1] == '\n' ||
+        dbg_print_tmp_buff[len-1] == '\r') ) {
+        was_enter = TRUE;
+    } else {
+        was_enter = FALSE;
+    }
+
+    OutputDebugString(&dbg_print_tmp_buff[0]);
+
+    va_end(ap);
+
+} // end PrintDbgConsole()
+#else // PRINT_DBG_CONSOLE
+VOID
+PrintDbgConsole(
+    PCHAR DebugMessage,
+    ...
+    )
+{
+} // end ClassDebugPrint()
+#endif //PRINT_DBG_CONSOLE
+
+BOOLEAN
+RtlTimeFieldsToTime(
+    IN PTIME_FIELDS TimeFields,
+    IN PLARGE_INTEGER Time
+    )
+{
+    SYSTEMTIME st;
+
+    st.wYear         = TimeFields->Year;
+    st.wMonth        = TimeFields->Month;
+    st.wDayOfWeek    = 0;
+    st.wDay          = TimeFields->Day;
+    st.wHour         = TimeFields->Hour;
+    st.wMinute       = TimeFields->Minute;
+    st.wSecond       = TimeFields->Second;
+    st.wMilliseconds = TimeFields->Milliseconds;
+
+    return SystemTimeToFileTime(&st, (PFILETIME)Time);
+} // end RtlTimeFieldsToTime()
+
+BOOLEAN
+RtlTimeToTimeFields(
+    IN PLARGE_INTEGER Time,
+    IN PTIME_FIELDS TimeFields
+    )
+{
+    SYSTEMTIME st;
+    BOOLEAN retval;
+
+    retval = FileTimeToSystemTime((PFILETIME)Time, &st);
+
+    TimeFields->Year         = st.wYear;
+    TimeFields->Month        = st.wMonth;
+    TimeFields->Weekday      = st.wDayOfWeek;
+    TimeFields->Day          = st.wDay;
+    TimeFields->Hour         = st.wHour;
+    TimeFields->Minute       = st.wMinute;
+    TimeFields->Second       = st.wSecond;
+    TimeFields->Milliseconds = st.wMilliseconds;
+
+    return retval;
+} // end ()
+
+#endif //NT_NATIVE_MODE
+
+#ifdef USE_THREAD_HEAPS
+
+HANDLE MemLock = NULL;
+
+VOID
+ExInitThreadPools()
+{
+    MemLock = CreateMutex(NULL, 0, NULL);
+}
+
+VOID
+ExDeInitThreadPools()
+{
+    if(MemLock)
+        CloseHandle(MemLock);
+}
+
+#define MAX_THREADS_WITH_OWN_POOL   128
+
+typedef struct _THREAD_POOL_LIST_ITEM {
+    HANDLE HeapHandle;
+    ULONG  ThreadId;
+} THREAD_POOL_LIST_ITEM, *PTHREAD_POOL_LIST_ITEM;
+
+ULONG LastThreadPool = -1;
+THREAD_POOL_LIST_ITEM ThreadPoolList[MAX_THREADS_WITH_OWN_POOL];
+
+extern "C"
+PVOID
+#ifdef KERNEL_MODE_MM_BEHAVIOR
+_ExAllocatePool_(
+#else
+ExAllocatePool(
+#endif
+    ULONG MemoryType,
+    ULONG Size
+    )
+{
+    ULONG i;
+    ULONG ThreadId = GetCurrentThreadId();
+    BOOLEAN found = FALSE;
+
+    WaitForSingleObject(MemLock,-1);
+
+    for(i=0; i<(LastThreadPool+1); i++) {
+        if(ThreadPoolList[i].ThreadId == ThreadId) {
+            found = TRUE;
+            break;
+        }
+    }
+    if(found) {
+        ReleaseMutex(MemLock);
+        return HeapAlloc(ThreadPoolList[i].HeapHandle, HEAP_NO_SERIALIZE, Size);
+    }
+    for(i=0; i<(LastThreadPool+1); i++) {
+        if(ThreadPoolList[i].ThreadId == -1) {
+            break;
+        }
+    }
+    if(i>=MAX_THREADS_WITH_OWN_POOL) {
+        ReleaseMutex(MemLock);
+        return NULL;
+    }
+    ThreadPoolList[i].ThreadId   = ThreadId;
+    ThreadPoolList[i].HeapHandle = HeapCreate(HEAP_NO_SERIALIZE, 128*PAGE_SIZE, 0);
+    if(!ThreadPoolList[i].HeapHandle) {
+        ThreadPoolList[i].ThreadId = -1;
+        ReleaseMutex(MemLock);
+        return NULL;
+    }
+
+    if(i+1 > LastThreadPool+1)
+        LastThreadPool = i;
+
+    ReleaseMutex(MemLock);
+        
+    return HeapAlloc(ThreadPoolList[i].HeapHandle, HEAP_NO_SERIALIZE, Size);
+
+} // end ExAllocatePool()
+
+extern "C"
+VOID
+#ifdef KERNEL_MODE_MM_BEHAVIOR
+_ExFreePool_(
+#else
+ExFreePool(
+#endif
+    PVOID Addr
+    )
+{
+    ULONG ThreadId = GetCurrentThreadId();
+    ULONG i;
+
+    WaitForSingleObject(MemLock,-1);
+    for(i=0; i<(LastThreadPool+1); i++) {
+        if(ThreadPoolList[i].ThreadId == ThreadId) {
+            break;
+        }
+    }
+    if(i+1 > LastThreadPool+1) {
+        // Not found
+        BrutePoint();
+        //__asm int 3;
+        return;
+    }
+    HeapFree(ThreadPoolList[i].HeapHandle, HEAP_NO_SERIALIZE, Addr);
+
+    ReleaseMutex(MemLock);
+
+} // end ExFreePool()
+
+extern "C"
+VOID
+ExFreeThreadPool()
+{
+    ULONG ThreadId = GetCurrentThreadId();
+    ULONG i;
+
+    WaitForSingleObject(MemLock,-1);
+    for(i=0; i<(LastThreadPool+1); i++) {
+        if(ThreadPoolList[i].ThreadId == ThreadId) {
+            break;
+        }
+    }
+    if(i+1 > LastThreadPool+1) {
+        // Not found
+        BrutePoint();
+        //__asm int 3;
+        return;
+    }
+    HeapDestroy(ThreadPoolList[i].HeapHandle);
+    ThreadPoolList[i].HeapHandle = INVALID_HANDLE_VALUE;
+    ThreadPoolList[i].ThreadId   = -1;
+
+    ReleaseMutex(MemLock);
+}
+
+#endif //USE_THREAD_HEAPS
+
+#if defined(KERNEL_MODE_MM_BEHAVIOR)
+extern "C"
+PVOID
+ExAllocatePool(
+    ULONG MemoryType,
+    ULONG Size
+    )
+{
+    PVOID Addr;
+    PVOID uAddr;
+    if(Size < PAGE_SIZE) {
+#ifdef USE_THREAD_HEAPS
+        Addr = _ExAllocatePool_(MemoryType, Size+8);
+#else
+        Addr = GlobalAlloc(GMEM_DISCARDABLE, Size+8);
+#endif
+        if(!Addr)
+            return NULL;
+        uAddr = ((PCHAR)Addr)+8;
+    } else {
+#ifdef USE_THREAD_HEAPS
+        Addr = _ExAllocatePool_(MemoryType, Size+PAGE_SIZE*2);
+#else
+        Addr = GlobalAlloc(GMEM_DISCARDABLE, Size+PAGE_SIZE*2);
+#endif
+        if(!Addr)
+            return NULL;
+        uAddr = (PVOID)(((ULONG)(((PCHAR)Addr)+PAGE_SIZE)) & ~(PAGE_SIZE-1));
+    }
+    *(((PULONG)uAddr)-2) = (ULONG)Addr;
+    *(((PULONG)uAddr)-1) = 0xFEDCBA98;
+    return uAddr;
+} // end ExAllocatePool()
+
+extern "C"
+VOID
+ExFreePool(
+    PVOID uAddr
+    )
+{
+    PVOID Addr;
+
+    if(*(((PULONG)uAddr)-1) == 0xFEDCBA98) {
+        Addr = (PVOID)(*(((PULONG)uAddr)-2));
+#ifdef USE_THREAD_HEAPS
+        _ExFreePool_(Addr);
+#else
+        GlobalFree(Addr);
+#endif
+        return;
+    }
+    BrutePoint();
+} // end ExFreePool()
+#endif //defined(KERNEL_MODE_MM_BEHAVIOR) || defined(NT_NATIVE_MODE)
+
+#ifdef _lphUdf
+#undef _lphUdf
+#endif //_lphUdf
+
+extern "C"
+BOOLEAN
+ProbeMemory(
+    PVOID   MemPtr,
+    ULONG   Length,
+    BOOLEAN ForWrite
+    )
+{
+    ULONG i;
+    UCHAR a;
+    if(!MemPtr && !Length)
+        return TRUE;
+    if(!MemPtr || !Length)
+        return FALSE;
+    _SEH2_TRY {
+        a = ((PCHAR)MemPtr)[Length-1];
+        if(ForWrite) {
+            ((PCHAR)MemPtr)[Length-1] = a;
+        }
+        for(i=0; i<Length; i+=PAGE_SIZE) {
+            a = ((PCHAR)MemPtr)[i];
+            if(ForWrite) {
+                ((PCHAR)MemPtr)[i] = a;
+            }
+        }
+    } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+        return FALSE;
+    } _SEH2_END;
+    return TRUE;
+} // end ProbeMemory()
+
+#ifdef NT_NATIVE_MODE
+#include "env_spec_nt.cpp"
+#endif //NT_NATIVE_MODE
diff --git a/reactos/drivers/filesystems/udfs/Include/env_spec_w32.h b/reactos/drivers/filesystems/udfs/Include/env_spec_w32.h
new file mode 100644 (file)
index 0000000..cef3a3b
--- /dev/null
@@ -0,0 +1,1034 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+/*************************************************************************
+*
+* File: env_spec_w32.h
+*
+* Module: User-mode applications (User mode execution only)
+*
+* Description:
+*   
+*
+* Author: Alter
+*
+*************************************************************************/
+
+#ifndef __ENV_SPEC_W32__H_
+#define __ENV_SPEC_W32__H_
+
+#ifdef NT_NATIVE_MODE
+//#include "ntddk.h" // include this for its native functions and defn's
+#include "nt_native.h"
+#else //NT_NATIVE_MODE
+#include <windows.h>
+#endif //NT_NATIVE_MODE
+#include "platform.h"
+//#ifndef WITHOUT_FORMATTER
+#include "udferr_usr.h"
+//#endif WITHOUT_FORMATTER
+
+#ifndef NT_NATIVE_MODE
+#ifdef ASSERT
+  #undef ASSERT
+  #define ASSERT(a)    if(!(a)) {__asm int 3;}
+#endif
+#endif //NT_NATIVE_MODE
+
+#ifndef MAXIMUM_FILENAME_LENGTH
+#define MAXIMUM_FILENAME_LENGTH MAX_PATH
+#endif //MAXIMUM_FILENAME_LENGTH
+
+#ifndef PAGE_SHIFT
+#define PAGE_SHIFT 12
+#endif //PAGE_SHIFT
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE (ULONG)0x1000
+#endif //PAGE_SIZE
+
+#ifndef PHYSICAL_ADDRESS
+#define PHYSICAL_ADDRESS  LARGE_INTEGER
+#endif //PHYSICAL_ADDRESS
+
+#define OS_SUCCESS(a)     NT_SUCCESS(a)
+#define OSSTATUS          NTSTATUS
+
+#if defined UDF_DBG || defined DEBUG
+#define DBG
+#ifndef CDRW_W32
+#define UDF_DBG
+#endif //CDRW_W32
+#endif 
+
+#define ERESEOURCE        ULONG
+#define PERESEOURCE       PULONG
+
+#define KEVENT            ULONG
+#define PKEVENT           PULONG
+
+typedef ULONG KSPIN_LOCK;  // winnt ntndis
+typedef KSPIN_LOCK *PKSPIN_LOCK;
+
+#ifndef NT_NATIVE_MODE
+// Status ot
+#define NTSTATUS LONG
+
+#define NT_SUCCESS(x) ( (NTSTATUS)(x)>=0 )
+
+#define PsGetCurrentThread()  GetCurrentThreadId()
+
+#define PsGetVersion(a,b,c,d) { \
+    OSVERSIONINFO OsVer;        \
+    OsVer.dwOSVersionInfoSize = sizeof(OsVer); \
+    GetVersionEx(&OsVer); \
+    if(a) (*(a)) = OsVer.dwMajorVersion; \
+    if(b) (*(b)) = OsVer.dwMinorVersion; \
+    if(c) (*(c)) = OsVer.dwBuildNumber;  \
+    if(d) (d)->Buffer = L"";  \
+    if(d) (d)->Length = 0;  \
+    if(d) (d)->MaximumLength = 0;  \
+}
+
+extern "C"
+VOID
+PrintDbgConsole(
+    PCHAR DebugMessage,
+    ...
+    );
+
+#else //NT_NATIVE_MODE
+#define HINSTANCE HANDLE
+#endif //NT_NATIVE_MODE
+
+typedef
+int (*PSKIN_INIT) (
+    HINSTANCE hInstance,      // handle to current instance
+    HINSTANCE hPrevInstance,  // handle to previous instance
+    int nCmdShow              // show state
+    );
+
+typedef
+int (*PSKIN_PRINTF) (
+    const char* Message,
+    ...
+    );
+
+typedef
+PWCHAR (__stdcall *PSKIN_GETCMDLINE) (
+    VOID
+    );
+
+typedef
+ULONG (__stdcall *PSKIN_MSG) (
+    ULONG MsgId,
+    ULONG MsgSubId,
+    PVOID DataIn,
+    ULONG DataInLen,
+    PVOID DataOut,
+    ULONG DataInOut
+    );
+
+typedef struct _SKIN_API {
+    PSKIN_INIT        Init;
+    PSKIN_PRINTF      Printf;
+    PSKIN_GETCMDLINE  GetCommandLine;
+    PSKIN_MSG         Msg;
+} SKIN_API, *PSKIN_API;
+
+#ifdef USE_SKIN_MODEL
+
+extern "C" PSKIN_API SkinAPI;
+extern PSKIN_API SkinLoad(
+    PWCHAR path,
+    HINSTANCE hInstance,      // handle to current instance
+    HINSTANCE hPrevInstance,  // handle to previous instance
+    int nCmdShow              // show state
+    );
+
+#define SkinPrintf                       SkinAPI->Printf
+#define SkinGetCmdLine                   SkinAPI->GetCommandLine
+#define SkinNotify(op, state, ctx, sz)   SkinAPI->Msg(op, state, ctx, sz, NULL, 0)
+#define SkinAsk(op, state, ctx, def)     SkinAPI->Msg(op, state, ctx, sizeof(ctx), NULL, 0)
+
+#else
+
+#define SkinLoad(path)    {;}
+
+#if defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+  #define SkinPrintf(x)                    {;}
+/*VOID
+inline
+SkinPrintf(
+    PCHAR Message,
+    ...
+    )
+{
+    //do nothing
+    return;
+}*/
+#else // defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+  #define SkinPrintf                       printf
+#endif
+
+#define SkinGetCmdLine                   GetCommandLineW
+#define SkinNotify(op, state, ctx)       {;}
+#define SkinAsk(op, state, ctx, def)     (def)
+
+#endif // defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+
+#if defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+
+  #if defined(PRINT_TO_DBG_LOG) || defined(PRINT_ALWAYS)
+    #define UserPrint(x) PrintDbgConsole x
+  #else
+    #define UserPrint(x) {;}
+  #endif // PRINT_TO_DBG_LOG
+
+#else // defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+
+  #if defined(PRINT_TO_DBG_LOG) || defined(PRINT_ALWAYS)
+
+    #define UserPrint(x) \
+    {                    \
+     SkinPrintf x ;          \
+     PrintDbgConsole x ; \
+    }
+
+  #else // PRINT_TO_DBG_LOG
+
+    #define UserPrint(x) \
+    {                    \
+     SkinPrintf x ;          \
+    }
+
+  #endif // PRINT_TO_DBG_LOG
+
+#endif // defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+
+#if defined(DBG) || defined(PRINT_ALWAYS)
+
+  #define DbgPrint SkinPrintf
+
+  #ifdef KdPrint
+    #undef KdPrint
+  #endif
+
+  #if defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+    #ifdef PRINT_TO_DBG_LOG
+      #define KdPrint(x) PrintDbgConsole x;
+    #else
+      #define KdPrint(x) {;}
+    #endif
+  #else
+
+    #if defined(PRINT_TO_DBG_LOG) || defined(PRINT_ALWAYS)
+      #define KdPrint(x) \
+      {                    \
+       SkinPrintf x ;          \
+       PrintDbgConsole x ; \
+      }
+    #else
+      #define KdPrint(x) \
+      {                    \
+       SkinPrintf x ;          \
+      }
+    #endif
+  #endif
+
+  #ifdef USE_MM_PRINT
+    #define MmPrint(_x_) DbgPrint _x_
+  #else
+    #define MmPrint(_x_) {NOTHING;}
+  #endif //USE_MM_PRINT
+
+  #ifdef USE_TIME_PRINT
+    extern ULONG UdfTimeStamp;
+    #define TmPrint(_x_) {UdfTimeStamp++;KdPrint(("TM:%d: ",UdfTimeStamp));KdPrint(_x_);}
+  #else
+    #define TmPrint KdPrint
+  #endif //USE_MM_PRINT
+
+  #ifdef USE_PERF_PRINT
+    #define PerfPrint(_x_) DbgPrint _x_
+  #else
+    #define PerfPrint(_x_) {NOTHING;}
+  #endif //USE_MM_PRINT
+
+#if defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+  #ifdef USE_AD_PRINT
+    #undef USE_AD_PRINT
+  #endif
+  #ifdef USE_TH_PRINT
+    #undef USE_TH_PRINT
+  #endif
+#endif
+
+  #ifdef USE_AD_PRINT
+    #define AdPrint(_x_) {DbgPrint("Thrd:%x:",PsGetCurrentThread());DbgPrint _x_;}
+  #else 
+    #define AdPrint(_x_) {NOTHING;}
+  #endif
+
+  #ifdef USE_TH_PRINT
+    #define ThPrint(_x_) {DbgPrint("Thrd:%x:",PsGetCurrentThread());DbgPrint _x_;}
+  #else
+    #define ThPrint(_x_) {NOTHING;}
+  #endif
+
+  #ifdef USE_DUMP_EXT
+    #define ExtPrint(_x_) DbgPrint _x_
+  #else
+    #define ExtPrint(_x_) {NOTHING;}
+  #endif //USE_MM_PRINT
+
+#else
+  #define KdPrint(x)     {NOTHING;}
+  #define MmPrint(_x_)   {NOTHING;}
+  #define TmPrint(_x_)   {NOTHING;}
+  #define PerfPrint(_x_) {NOTHING;}
+  #define AdPrint(_x_)   {NOTHING;}
+  #define ThPrint(_x_)   {NOTHING;}
+  #define ExtPrint(_x_)  {NOTHING;}
+#endif
+
+#define DbgTouch(a)
+
+#ifndef NT_NATIVE_MODE
+#include "assert.h"
+
+#define ASSERT(_x_)   assert(_x_)
+#define UDFTouch(a)
+
+#endif //NT_NATIVE_MODE
+
+#define NonPagedPool            0
+#define PagedPool               1
+//#define NonPagedPoolMustSucceed 2
+#define NonPagedPoolCacheAligned 4
+
+#define KdDump(a,b)                         \
+if((a)!=NULL) {                             \
+    ULONG i;                                \
+    for(i=0; i<(b); i++) {                  \
+        ULONG c;                            \
+        c = (ULONG)(*(((PUCHAR)(a))+i));    \
+        KdPrint(("%2.2x ",c));              \
+        if ((i & 0x0f) == 0x0f) KdPrint(("\n"));   \
+    }                                       \
+    KdPrint(("\n"));                        \
+}
+
+//mem ot
+//#define ExAllocatePool(hernya,size) MyAllocatePool(size)
+//#define ExFreePool(size) MyFreePool((PCHAR)(size))
+//#define SystemAllocatePool(hernya,size) GlobalAlloc(GMEM_DISCARDABLE, size);
+//#define SystemFreePool(addr) GlobalFree((PVOID)(addr))
+#define DbgMoveMemory     RtlMoveMemory
+#define DbgCompareMemory  RtlCompareMemory
+#define DbgCopyMemory     RtlCopyMemory
+#define DbgAllocatePool   ExAllocatePool
+#define DbgAllocatePoolWithTag(a,b,c)   ExAllocatePool(a,b)
+#define DbgFreePool       ExFreePool
+
+#ifdef NT_NATIVE_MODE
+/*
+#define GlobalAlloc(foo, size)  MyGlobalAlloc( size );
+#define GlobalFree(ptr)         MyGlobalFree( ptr );
+
+extern "C"
+PVOID MyGlobalAlloc(ULONG Size);
+
+extern "C"
+VOID  MyGlobalFree(PVOID Addr);
+*/
+#endif
+
+#if !defined(KERNEL_MODE_MM_BEHAVIOR) && !defined(USE_THREAD_HEAPS)
+#define ExAllocatePoolWithTag(hernya,size,tag) GlobalAlloc(GMEM_DISCARDABLE, (size))
+#define ExAllocatePool(hernya,size) GlobalAlloc(GMEM_DISCARDABLE, (size))
+#define ExFreePool(addr) GlobalFree((PVOID)(addr))
+#endif
+
+#if defined(KERNEL_MODE_MM_BEHAVIOR) || defined(USE_THREAD_HEAPS)
+#define ExAllocatePoolWithTag(MemoryType,size,tag) ExAllocatePool((MemoryType), (size))
+
+extern "C"
+PVOID ExAllocatePool(ULONG MemoryType, ULONG Size);
+
+extern "C"
+VOID  ExFreePool(PVOID Addr);
+#endif //KERNEL_MODE_MM_BEHAVIOR || USE_THREAD_HEAPS
+
+#ifndef NT_NATIVE_MODE
+
+//string ot
+typedef struct _UNICODE_STRING {
+    USHORT Length;
+    USHORT MaximumLength;
+    PWSTR  Buffer;
+} UNICODE_STRING;
+typedef UNICODE_STRING *PUNICODE_STRING;
+
+typedef struct _ANSI_STRING {
+    USHORT Length;
+    USHORT MaximumLength;
+    PSTR   Buffer;
+} ANSI_STRING;
+typedef ANSI_STRING *PANSI_STRING;
+
+#endif //NT_NATIVE_MODE
+
+#define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG)(OFFSET) - (ULONG)(BASE)))
+
+// Device object ot
+
+#ifndef DO_UNLOAD_PENDING
+// Define Device Object (DO) flags
+//
+
+#define DO_UNLOAD_PENDING               0x00000001
+#define DO_VERIFY_VOLUME                0x00000002
+#define DO_BUFFERED_IO                  0x00000004
+#define DO_EXCLUSIVE                    0x00000008
+#define DO_DIRECT_IO                    0x00000010
+#define DO_MAP_IO_BUFFER                0x00000020
+#define DO_DEVICE_HAS_NAME              0x00000040
+#define DO_DEVICE_INITIALIZING          0x00000080
+#define DO_SYSTEM_BOOT_PARTITION        0x00000100
+#define DO_LONG_TERM_REQUESTS           0x00000200
+#define DO_NEVER_LAST_DEVICE            0x00000400
+#define DO_SHUTDOWN_REGISTERED          0x00000800
+
+#endif //DO_UNLOAD_PENDING
+
+#ifdef NT_NATIVE_MODE
+#define _DEVICE_OBJECT _MY_DEVICE_OBJECT
+#define DEVICE_OBJECT  MY_DEVICE_OBJECT
+#define PDEVICE_OBJECT PMY_DEVICE_OBJECT
+#endif //NT_NATIVE_MODE
+
+typedef struct _DEVICE_OBJECT {
+    
+#ifndef LIBUDF
+    
+    HANDLE h;
+    PVOID  DeviceExtension;
+    ULONG  Flags;
+    ULONG  AlignmentRequirement;
+    UCHAR  StackSize;
+
+#endif // LIBUDF
+
+
+#ifdef LIBUDFFMT
+
+    struct _UDF_FMT_PARAMETERS* cbio;
+    PVOID  lpContext;
+
+#else
+#ifdef LIBUDF
+    PVOID  lpContext;
+#endif // LIBUDF
+#endif // LIBUDFFMT
+
+} DEVICE_OBJECT, *PDEVICE_OBJECT;
+
+#ifndef CDRW_W32
+/*
+typedef ULONG DEVICE_OBJECT;
+typedef ULONG PDEVICE_OBJECT;
+*/
+#define INVALID_PACKET 0x01
+
+typedef struct _PACKET {
+    // Node Identifier
+//  UDFIdentifier               NodeIdentifier; 
+    // Pointer to the buffer (in non-paged pool)
+    PCHAR           buffer;
+    // Offset, from which this data was read
+    LARGE_INTEGER   offset;
+    // Flags
+    UCHAR           flags;
+} PACKET, *PPACKET;
+
+#define UDFInitPacket(x) STATUS_SUCCESS
+#endif //CDRW_W32
+
+#define try_return(S)   { S; goto try_exit; }
+#define NOTHING
+
+#define FlagOn(x,f) ((x) & (f))
+
+#define RtlCompareMemory(s1,s2,l)  MyRtlCompareMemory(s1,s2,l)
+// Structure ot
+extern "C"
+ULONG
+MyRtlCompareMemory(
+    PVOID s1,
+    PVOID s2,
+    ULONG len
+    );
+//#define RtlCompareMemory(d1,d2,l)   (ULONG)(memcmp (d1,d2,l))
+
+#define KeSetEvent(pEvt, foo, foo2)          {NOTHING;}
+#define KeInitializeEvent(pEvt, foo, foo2)   {NOTHING;}
+#define KeWaitForSingleObject(pEvt, foo, a, b, c)     {NOTHING;}
+#define DbgWaitForSingleObject(o, to)   KeWaitForSingleObject(o, Executive, KernelMode, FALSE, to);
+//#define DbgWaitForSingleObject   KeWaitForSingleObject
+#ifdef NT_NATIVE_MODE
+#define KeDelayExecutionThread(mode, foo, t)  { NtDelayExecution(false, t); }
+#else //NT_NATIVE_MODE
+#define KeDelayExecutionThread(mode, foo, t) { Sleep( abs((LONG)(((t)->QuadPart)/10000)) ); }
+#endif //NT_NATIVE_MODE
+
+/*#define RtlCompareUnicodeString(s1,s2,cs) \
+ (((s1)->Length == (s2)->Length) && \
+  (RtlCompareMemory(s1,s2,(s1)->Length))) 
+*/
+#ifndef CDRW_W32
+#ifdef _X86_
+
+// This is an illegal use of INT3
+#define UDFBreakPoint() __asm int 3
+#else // _X86_
+
+#define UDFBreakPoint() DbgBreakPoint()
+#endif // _X86_
+
+#ifdef BRUTE
+#define BrutePoint() UDFBreakPoint()
+#else
+#define BrutePoint() {}
+#endif // BRUTE
+
+#ifdef VALIDATE_STRUCTURES
+#define ValidateFileInfo(fi)            \
+{    /* validate FileInfo */            \
+    if((fi)->IntegrityTag) {            \
+        KdPrint(("UDF: ERROR! Using deallocated structure !!!\n"));\
+        /*BrutePoint();*/                   \
+    }                                   \
+}
+#else
+#define ValidateFileInfo(fi)  {}
+#endif
+
+#else //CDRW_W32
+
+#ifdef BRUTE
+#ifdef _X86_
+
+// This is an illegal use of INT3
+#define BrutePoint() __asm int 3
+#else // _X86_
+
+#define BrutePoint() DbgBreakPoint()
+#endif // _X86_
+#else
+#define BrutePoint() {}
+#endif // BRUTE
+
+#endif //CDRW_W32
+
+#ifndef NT_NATIVE_MODE
+
+extern "C"
+ULONG
+RtlCompareUnicodeString(
+    PUNICODE_STRING s1,
+    PUNICODE_STRING s2,
+    BOOLEAN UpCase);
+
+extern "C"
+NTSTATUS
+RtlUpcaseUnicodeString(
+    PUNICODE_STRING dst,
+    PUNICODE_STRING src,
+    BOOLEAN Alloc
+    );
+
+extern "C"
+NTSTATUS
+RtlAppendUnicodeToString(
+    IN PUNICODE_STRING Str1,
+    IN PWSTR Str2
+    );
+
+#endif //NT_NATIVE_MODE
+
+extern "C"
+NTSTATUS
+MyInitUnicodeString(
+    IN PUNICODE_STRING Str1,
+    IN PCWSTR Str2
+    );
+
+#ifndef NT_NATIVE_MODE
+#define KeQuerySystemTime(t)     GetSystemTimeAsFileTime((LPFILETIME)(t));
+
+typedef struct _FILE_BOTH_DIR_INFORMATION {
+    ULONG           NextEntryOffset;
+    ULONG           FileIndex;
+    LARGE_INTEGER   CreationTime;
+    LARGE_INTEGER   LastAccessTime;
+    LARGE_INTEGER   LastWriteTime;
+    LARGE_INTEGER   ChangeTime;
+    LARGE_INTEGER   EndOfFile;
+    LARGE_INTEGER   AllocationSize;
+    ULONG           FileAttributes;
+    ULONG           FileNameLength;
+    ULONG           EaSize;
+    CCHAR           ShortNameLength;
+    WCHAR           ShortName[12];
+    WCHAR           FileName[1];
+} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
+
+#endif //NT_NATIVE_MODE
+
+typedef UCHAR KIRQL;
+typedef KIRQL *PKIRQL;
+
+typedef ULONG ERESOURCE;
+typedef ERESOURCE *PERESOURCE;
+
+#define KeRaiseIrql(irql, oldIrql)                    \
+{                                                     \
+    *oldIrql = 0;                                     \
+}
+
+#define KeLowerIrql(oldIrql)  {;}
+
+#define KeInitializeSpinLock(sl)                    \
+{                                                     \
+  *(sl) = 0;                                          \
+}
+
+#define KeAcquireSpinLock(sl,irql)                    \
+{                                                     \
+    ULONG isLocked = TRUE;                            \
+    while(isLocked) AcquireXLock(*(sl), isLocked, TRUE);\
+}
+
+#define ExAcquireResourceExclusiveLite(res, wait)     \
+{                                                     \
+    ULONG isLocked = TRUE;                            \
+    while(isLocked) AcquireXLock(*(res), isLocked, TRUE);\
+}
+
+#define ExAcquireResourceSharedLite(res, wait)        \
+{                                                     \
+    ULONG isLocked = TRUE;                            \
+    while(isLocked) AcquireXLock(*(res), isLocked, TRUE);\
+}
+
+#define KeReleaseSpinLock(sl,irql)                    \
+{                                                     \
+    ULONG isLocked;                                   \
+    AcquireXLock(*(sl), isLocked, FALSE);             \
+}
+
+#define ExGetCurrentResourceThread()  0
+
+#define ExReleaseResourceForThreadLite(res, thrdID)   \
+{                                                     \
+    ULONG isLocked;                                   \
+    AcquireXLock(*(res), isLocked, FALSE);            \
+}
+
+NTSTATUS inline ExInitializeResourceLite(PULONG res)
+{
+   *(res) = 0;
+   return STATUS_SUCCESS;
+}
+
+#define ExDeleteResourceLite(res)                     \
+{                                                     \
+   *(res) = 0;                                        \
+}
+
+#define ExConvertExclusiveToSharedLite(res) {/* do nothing */}
+
+#ifndef CDRW_W32
+
+#define UDFAcquireResourceExclusive(Resource,CanWait)  \
+    ExAcquireResourceExclusiveLite((Resource),(CanWait)) 
+#define UDFAcquireResourceShared(Resource,CanWait) \
+    ExAcquireResourceSharedLite((Resource),(CanWait)) 
+// a convenient macro (must be invoked in the context of the thread that acquired the resource)
+#define UDFReleaseResource(Resource)    \
+    ExReleaseResourceForThreadLite((Resource), ExGetCurrentResourceThread())
+#define UDFDeleteResource(Resource)    \
+    ExDeleteResourceLite((Resource))
+#define UDFConvertExclusiveToSharedLite(Resource) \
+    ExConvertExclusiveToSharedLite((Resource))
+#define UDFInitializeResourceLite(Resource) \
+    ExInitializeResourceLite((Resource))
+#define UDFAcquireSharedStarveExclusive(Resource,CanWait) \
+    ExAcquireSharedStarveExclusive((Resource),(CanWait))
+#define UDFAcquireSharedWaitForExclusive(Resource,CanWait) \
+    ExAcquireSharedWaitForExclusive((Resource),(CanWait))
+//#define UDFDebugAcquireResourceExclusiveLite(a,b,c,d) ExAcquireResourceExclusiveLite(a,b)
+
+#define UDFInterlockedIncrement(addr) \
+    ((*addr)++)
+#define UDFInterlockedDecrement(addr) \
+    ((*addr)--)
+int
+__inline
+UDFInterlockedExchangeAdd(PLONG addr, LONG i) {
+    LONG Old = (*addr);
+    (*addr) += i;
+    return Old;
+}
+
+#endif //CDRW_W32
+
+//
+// Interrupt Request Level definitions
+//
+
+#define PASSIVE_LEVEL 0             // Passive release level
+#define LOW_LEVEL 0                 // Lowest interrupt level
+#define APC_LEVEL 1                 // APC interrupt level
+#define DISPATCH_LEVEL 2            // Dispatcher level
+
+#define PROFILE_LEVEL 27            // timer used for profiling.
+#define CLOCK1_LEVEL 28             // Interval clock 1 level - Not used on x86
+#define CLOCK2_LEVEL 28             // Interval clock 2 level
+#define IPI_LEVEL 29                // Interprocessor interrupt level
+#define POWER_LEVEL 30              // Power failure level
+#define HIGH_LEVEL 31               // Highest interrupt level
+#define SYNCH_LEVEL (IPI_LEVEL-1)   // synchronization level
+
+#define KeGetCurrentIrql()      PASSIVE_LEVEL
+
+#ifndef NT_NATIVE_MODE
+
+typedef struct _TIME_FIELDS {
+    USHORT Year;        // range [1601...]
+    USHORT Month;       // range [1..12]
+    USHORT Day;         // range [1..31]
+    USHORT Hour;        // range [0..23]
+    USHORT Minute;      // range [0..59]
+    USHORT Second;      // range [0..59]
+    USHORT Milliseconds;// range [0..999]
+    USHORT Weekday;     // range [0..6] == [Sunday..Saturday]
+} TIME_FIELDS;
+typedef TIME_FIELDS *PTIME_FIELDS;
+
+//#define RtlTimeFieldsToTime(a,b)     TRUE
+BOOLEAN
+RtlTimeFieldsToTime(
+    IN PTIME_FIELDS TimeFields,
+    IN PLARGE_INTEGER Time
+    );
+
+#define ExSystemTimeToLocalTime(SysTime, LocTime)     FileTimeToLocalFileTime((PFILETIME)(SysTime), (PFILETIME)(LocTime))
+
+//#define RtlTimeToTimeFields(a,b) {}
+BOOLEAN
+RtlTimeToTimeFields(
+    IN PLARGE_INTEGER Time,
+    IN PTIME_FIELDS TimeFields
+    );
+
+#define ExLocalTimeToSystemTime(LocTime, SysTime)     LocalFileTimeToFileTime((PFILETIME)(LocTime), (PFILETIME)(SysTime))
+
+#endif //NT_NATIVE_MODE
+
+#ifndef CDRW_W32
+
+typedef struct _FSRTL_COMMON_FCB_HEADER {
+    SHORT           NodeTypeCode;
+    SHORT           NodeByteSize;
+    UCHAR           Flags;
+    UCHAR           IsFastIoPossible;
+#if (_WIN32_WINNT >= 0x0400)
+    UCHAR           Flags2;
+    UCHAR           Reserved;
+#endif // (_WIN32_WINNT >= 0x0400)
+    PERESOURCE      Resource;
+    PERESOURCE      PagingIoResource;
+    LARGE_INTEGER   AllocationSize;
+    LARGE_INTEGER   FileSize;
+    LARGE_INTEGER   ValidDataLength;
+} FSRTL_COMMON_FCB_HEADER, *PFSRTL_COMMON_FCB_HEADER;
+
+typedef struct _SECTION_OBJECT_POINTERS {
+    PVOID DataSectionObject;
+    PVOID SharedCacheMap;
+    PVOID ImageSectionObject;
+} SECTION_OBJECT_POINTERS;
+typedef SECTION_OBJECT_POINTERS *PSECTION_OBJECT_POINTERS;
+
+
+extern NTSTATUS UDFPhReadSynchronous(
+                   PDEVICE_OBJECT      DeviceObject,
+                   PVOID           Buffer,
+                   ULONG           Length,
+                   LONGLONG        Offset,
+                   PULONG          ReadBytes,
+                   ULONG           Flags);
+
+extern NTSTATUS UDFPhWriteSynchronous(
+                   PDEVICE_OBJECT  DeviceObject,   // the physical device object
+                   PVOID           Buffer,
+                   ULONG           Length,
+                   LONGLONG        Offset,
+                   PULONG          WrittenBytes,
+                   ULONG           Flags);
+
+#if 0
+extern NTSTATUS
+UDFPhWriteVerifySynchronous(
+    PDEVICE_OBJECT  DeviceObject,   // the physical device object
+    PVOID           Buffer,
+    ULONG           Length,
+    LONGLONG        Offset,
+    PULONG          WrittenBytes,
+    ULONG           Flags
+    );
+#endif
+
+#define UDFPhWriteVerifySynchronous   UDFPhWriteSynchronous
+
+extern NTSTATUS UDFPhSendIOCTL(
+    IN ULONG IoControlCode,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PVOID InputBuffer ,
+    IN ULONG InputBufferLength,
+    OUT PVOID OutputBuffer ,
+    IN ULONG OutputBufferLength,
+    IN BOOLEAN OverrideVerify,
+    OUT PVOID Iosb OPTIONAL);
+
+#endif //CDRW_W32
+
+VOID set_image_size(HANDLE h,
+//                    ULONG LBA);
+                    int64  len);
+
+#ifdef UDF_FORMAT_MEDIA
+struct _UDFVolumeControlBlock;
+#endif
+
+#ifndef UDF_FORMAT_MEDIA
+ULONG write(
+            HANDLE h,
+            PCHAR buff,
+            ULONG len);
+#endif
+
+extern "C"
+HANDLE
+my_open(
+#ifndef CDRW_W32
+    struct _UDFVolumeControlBlock* Vcb,
+#endif //CDRW_W32
+    PWCHAR fn);
+
+#ifdef UDF_FORMAT_MEDIA
+struct _UDFFmtState;
+#endif //UDF_FORMAT_MEDIA
+
+extern
+void
+my_exit(
+#ifdef UDF_FORMAT_MEDIA
+    struct _UDFFmtState* fms,
+#endif //UDF_FORMAT_MEDIA
+    int rc
+    );
+
+#ifndef CDRW_W32
+uint64 udf_lseek64(HANDLE fd, uint64 offset, int whence);
+#endif //CDRW_W32
+
+#ifdef LIBUDFFMT
+BOOLEAN
+udf_get_sizes(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN ULONG* blocks
+    );
+#endif //LIBUDFFMT
+
+int64
+get_file_size(
+    HANDLE h
+    );
+
+int64
+set_file_pointer(
+    HANDLE h,
+    int64 sz
+    );
+
+#ifndef NT_NATIVE_MODE
+typedef struct _IO_STATUS_BLOCK {
+    ULONG Status;
+    ULONG Information;
+} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
+#endif //NT_NATIVE_MODE
+
+
+#ifndef UDF_FORMAT_MEDIA
+extern ULONG   LockMode;
+extern BOOLEAN open_as_device;
+extern BOOLEAN opt_invalidate_volume;
+#endif //UDF_FORMAT_MEDIA
+
+extern "C"
+ULONG
+MyLockVolume(
+    HANDLE h,
+    ULONG* pLockMode // OUT
+    );
+
+extern "C"
+ULONG
+MyUnlockVolume(
+    HANDLE h,
+    ULONG* pLockMode // IN
+    );
+
+#ifndef CDRW_W32
+ULONG
+UDFGetDevType(PDEVICE_OBJECT DeviceObject);
+#endif //CDRW_W32
+
+#ifndef INVALID_HANDLE_VALUE
+#define INVALID_HANDLE_VALUE    ((HANDLE)(-1))
+#endif
+
+#ifndef ANSI_DOS_STAR
+
+#define ANSI_DOS_STAR   ('<')
+#define ANSI_DOS_QM     ('>')
+#define ANSI_DOS_DOT    ('"')
+
+#define DOS_STAR        (L'<')
+#define DOS_QM          (L'>')
+#define DOS_DOT         (L'"')
+
+#endif //ANSI_DOS_STAR
+
+extern "C"
+BOOLEAN
+ProbeMemory(
+    PVOID   MemPtr,
+    ULONG   Length,
+    BOOLEAN ForWrite
+    );
+
+#ifdef NT_NATIVE_MODE
+#include "env_spec_nt.h"
+#endif //NT_NATIVE_MODE
+
+#ifndef InitializeListHead
+
+//
+//  Doubly-linked list manipulation routines.  Implemented as macros
+//  but logically these are procedures.
+//
+
+//
+//  VOID
+//  InitializeListHead(
+//      PLIST_ENTRY ListHead
+//      );
+//
+
+#define InitializeListHead(ListHead) (\
+    (ListHead)->Flink = (ListHead)->Blink = (ListHead))
+
+//
+//  BOOLEAN
+//  IsListEmpty(
+//      PLIST_ENTRY ListHead
+//      );
+//
+
+#define IsListEmpty(ListHead) \
+    ((ListHead)->Flink == (ListHead))
+
+//
+//  PLIST_ENTRY
+//  RemoveHeadList(
+//      PLIST_ENTRY ListHead
+//      );
+//
+
+#define RemoveHeadList(ListHead) \
+    (ListHead)->Flink;\
+    {RemoveEntryList((ListHead)->Flink)}
+
+//
+//  PLIST_ENTRY
+//  RemoveTailList(
+//      PLIST_ENTRY ListHead
+//      );
+//
+
+#define RemoveTailList(ListHead) \
+    (ListHead)->Blink;\
+    {RemoveEntryList((ListHead)->Blink)}
+
+//
+//  VOID
+//  RemoveEntryList(
+//      PLIST_ENTRY Entry
+//      );
+//
+
+#define RemoveEntryList(Entry) {\
+    PLIST_ENTRY _EX_Blink;\
+    PLIST_ENTRY _EX_Flink;\
+    _EX_Flink = (Entry)->Flink;\
+    _EX_Blink = (Entry)->Blink;\
+    _EX_Blink->Flink = _EX_Flink;\
+    _EX_Flink->Blink = _EX_Blink;\
+    }
+
+//
+//  VOID
+//  InsertTailList(
+//      PLIST_ENTRY ListHead,
+//      PLIST_ENTRY Entry
+//      );
+//
+
+#define InsertTailList(ListHead,Entry) {\
+    PLIST_ENTRY _EX_Blink;\
+    PLIST_ENTRY _EX_ListHead;\
+    _EX_ListHead = (ListHead);\
+    _EX_Blink = _EX_ListHead->Blink;\
+    (Entry)->Flink = _EX_ListHead;\
+    (Entry)->Blink = _EX_Blink;\
+    _EX_Blink->Flink = (Entry);\
+    _EX_ListHead->Blink = (Entry);\
+    }
+
+//
+//  VOID
+//  InsertHeadList(
+//      PLIST_ENTRY ListHead,
+//      PLIST_ENTRY Entry
+//      );
+//
+
+#define InsertHeadList(ListHead,Entry) {\
+    PLIST_ENTRY _EX_Flink;\
+    PLIST_ENTRY _EX_ListHead;\
+    _EX_ListHead = (ListHead);\
+    _EX_Flink = _EX_ListHead->Flink;\
+    (Entry)->Flink = _EX_Flink;\
+    (Entry)->Blink = _EX_ListHead;\
+    _EX_Flink->Blink = (Entry);\
+    _EX_ListHead->Flink = (Entry);\
+    }
+
+#endif //InitializeListHead
+
+#endif  // __ENV_SPEC_W32__H_
diff --git a/reactos/drivers/filesystems/udfs/Include/format_common.cpp b/reactos/drivers/filesystems/udfs/Include/format_common.cpp
new file mode 100644 (file)
index 0000000..636e096
--- /dev/null
@@ -0,0 +1,262 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+/// Initial drive selection from command line.
+CHAR szDisc[4] = "";
+BOOL bChanger = FALSE;
+
+/// Return CD-RW device type
+JS_DEVICE_TYPE
+CheckCDType(
+    PCHAR m_szFile,
+    PCHAR VendorId
+    )
+{
+    HANDLE hDevice;
+    CHAR szDeviceName[256];
+    CHAR ioBuf[4096];
+    ULONG RC;
+    BOOL DvdRW  = false;
+    BOOL DvdpRW = false;
+    BOOL DvdRAM = false;
+    BOOL DvdpR = false;
+    BOOL DvdR = false;
+
+    bChanger = FALSE;
+
+    // Make string representing full path
+    sprintf(szDeviceName, "\\\\.\\%s", m_szFile);
+    if (szDeviceName[strlen(szDeviceName)-1] == '\\') szDeviceName[strlen(szDeviceName)-1] = '\0';
+
+    // Open device volume
+    hDevice = OpenOurVolume(szDeviceName);
+
+    if (hDevice == ((HANDLE)-1)) {   
+        strcpy(VendorId,"");
+        return BUSY;
+    } else {             
+         
+        // Get our cdrw.sys signature
+        RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_SIGNATURE,hDevice,
+                            &ioBuf,sizeof(GET_SIGNATURE_USER_OUT),
+                            &ioBuf,sizeof(GET_SIGNATURE_USER_OUT),FALSE,NULL);
+
+        if (RC == 1) {
+            // Get device information
+            RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_DEVICE_INFO,hDevice,
+                               &ioBuf,sizeof(GET_DEVICE_INFO_USER_OUT),
+                               &ioBuf,sizeof(GET_DEVICE_INFO_USER_OUT),FALSE,NULL);
+            if (RC != 1) {
+                strcpy(VendorId,"Unknown Vendor");
+            } else {
+                if(((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features & CDRW_FEATURE_CHANGER)
+                    bChanger = TRUE;
+                strcpy(VendorId,(PCHAR)&(((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->VendorId[0]));
+                if (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features & CDRW_FEATURE_GET_CFG) {
+                    DvdRW = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDRW_RESTRICTED_OVERWRITE) & 1;
+                    DvdRAM = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDRAM) & 1;
+                    DvdpRW = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDpRW) & 1;
+                    DvdR = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDR) & 1;
+                    DvdpR = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDpR) & 1;
+                }
+            }
+
+            // Get device capabilities
+            RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_CAPABILITIES,hDevice,
+                                &ioBuf,sizeof(GET_CAPABILITIES_USER_OUT),
+                                &ioBuf,sizeof(GET_CAPABILITIES_USER_OUT),FALSE,NULL);
+            if(RC != 1) {
+                CloseHandle(hDevice);
+                return OTHER;
+            }
+
+            // Check capabilities
+            if(((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & (DevCap_write_cd_r | DevCap_write_cd_rw | DevCap_write_dvd_ram | DevCap_write_dvd_r) ||
+              DvdRW || DvdpRW || DvdRAM) {
+                
+                if (DvdRAM || ((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & DevCap_write_dvd_ram) {
+                    CloseHandle(hDevice);
+                    return DVDRAM;
+                }
+/*                if (DvdR) {
+                    CloseHandle(hDevice);
+                    return DVDR;
+                }*/
+                if (DvdRW) {
+                    CloseHandle(hDevice);
+                    return DVDRW;
+                }
+                if (DvdpRW) {
+                    CloseHandle(hDevice);
+                    return DVDPRW;
+                }
+/*                if (DvdpR) {
+                    CloseHandle(hDevice);
+                    return DVDPR;
+                }*/
+                if (((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & DevCap_write_dvd_r) {
+                    CloseHandle(hDevice);
+                    return DVDR;
+                }
+                if (((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & DevCap_write_cd_rw) {
+                    CloseHandle(hDevice);
+                    return CDRW;
+                }
+                if (((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & DevCap_write_cd_r) {
+                    CloseHandle(hDevice);
+                    return CDR;
+                }
+            }
+            else {
+                CloseHandle(hDevice);
+                return OTHER;
+            }
+        } else {
+            strcpy(VendorId,"Unknown Vendor");
+        }
+        CloseHandle(hDevice);
+    }
+                
+    return OTHER;
+} // end CheckCDType()
+
+/** Intialize asbtract device list via calls to CallBack function.
+    \param hDlg Not used.
+    \param hwndControl Passed to the CallBack function. See #PADD_DEVICE.
+    \param CallBack Callback function. Called on each CD device in system.
+*/
+void
+InitDeviceList(
+    HWND hDlg,
+    HWND hwndControl,
+    PADD_DEVICE CallBack
+    )
+{
+    char    Buffer[MAX_PATH] = "";
+    char    VendorId[25];
+    char    seps[] = ",";
+    char*   token;
+    char    info[MAX_PATH];
+    bool    add_drive = false;
+
+    JS_DEVICE_TYPE  drive_type;
+
+    // Get all device letter in system
+    GetLogicalDriveStrings((DWORD)MAX_PATH,(LPTSTR)&Buffer);
+    token = (char *)&Buffer;
+    // Replace all zeroes with comma.
+    while (token != NULL) {
+        token = (char *)memchr(Buffer,'\0',MAX_PATH);
+        if (token) {
+            if (*(token-1) == ',') {
+                token = NULL;
+            } else {
+                *token=',';
+            }
+        }
+    }
+    // Parse string of drive letters separated by comma
+    token = strtok((char *)&Buffer,seps);
+    while (token != NULL) {
+        add_drive = false;
+        switch (GetDriveType(token)) {
+/*
+            case DRIVE_FIXED:   
+                add_drive = true;
+                break;
+*/
+            case DRIVE_CDROM:   
+                // Determine CD/DVD-ROM type (R,RW,RAM,other)
+                drive_type = CheckCDType(token,&VendorId[0]);
+                add_drive = true;
+                break;
+        }
+        if (add_drive) {
+
+            // Append to drive letter VendorId
+            strncpy(info,token,strlen(token)-1);
+            info[strlen(token)-1]='\0';
+            strcat(info,"  ");
+            strcat(info,VendorId);
+
+            BOOL bSelect = !strcmp(strupr(szDisc),strupr(token));
+            if (drive_type != OTHER) {
+                CallBack(hwndControl,token,info,MediaTypeStrings[drive_type],bSelect); 
+            } else {
+                CallBack(hwndControl,token,info,"[Unsupported]",FALSE); 
+            }
+
+        }
+        // Move to the next drive letter in string
+        token = strtok(NULL,seps);
+    }
+} // end InitDeviceList()
+
+HANDLE
+FmtAcquireDrive_(
+    PCHAR _Drive,
+    CHAR Level
+    )
+{
+    WCHAR LockName[32];
+    HANDLE evt;
+
+    WCHAR Drive[1];
+    Drive[0] = _Drive[0] & ~('a' ^ 'A');
+
+    swprintf(LockName, L"DwFmtLock_%1.1S%d", Drive, Level);
+    evt = CreatePublicEvent(LockName);
+    if(!evt) {
+        return NULL;
+    }
+    if(GetLastError() == ERROR_ALREADY_EXISTS) {
+        CloseHandle(evt);
+        return INVALID_HANDLE_VALUE;
+    }
+    return evt;
+} // end FmtAcquireDrive_()
+
+HANDLE
+FmtAcquireDrive(
+    PCHAR Drive,
+    CHAR Level
+    )
+{
+    HANDLE evt;
+
+    evt = FmtAcquireDrive_(Drive, Level);
+    if(!evt || evt == INVALID_HANDLE_VALUE) {
+        return NULL;
+    }
+    return evt;
+} // end FmtAcquireDrive()
+
+BOOLEAN
+FmtIsDriveAcquired(
+    PCHAR Drive,
+    CHAR Level
+    )
+{
+    HANDLE evt;
+
+    evt = FmtAcquireDrive_(Drive, Level);
+    if(evt == INVALID_HANDLE_VALUE) {
+        return TRUE;
+    }
+    if(evt) {
+        CloseHandle(evt);
+    }
+    return FALSE;
+} // end FmtIsDriveAcquired()
+
+VOID
+FmtReleaseDrive(
+    HANDLE evt
+    )
+{
+    if(evt) {
+        CloseHandle(evt);
+    }
+} // end FmtReleaseDrive()
diff --git a/reactos/drivers/filesystems/udfs/Include/format_common.h b/reactos/drivers/filesystems/udfs/Include/format_common.h
new file mode 100644 (file)
index 0000000..85d9634
--- /dev/null
@@ -0,0 +1,41 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+JS_DEVICE_TYPE
+CheckCDType(
+    PCHAR m_szFile,
+    PCHAR VendorId
+    );
+
+typedef void (*PADD_DEVICE)(HWND hwndControl, PCHAR Drive, PCHAR Line1, PCHAR Line2,BOOL bSelect);
+
+void
+InitDeviceList(
+    HWND hDlg,
+    HWND hwndControl,
+    PADD_DEVICE CallBack
+    );
+
+extern CHAR szDisc[4];
+extern BOOL bChanger;
+
+HANDLE
+FmtAcquireDrive(
+    PCHAR Drive,
+    CHAR Level
+    );
+
+#define FmtAcquireDriveW(Drive, Level)    FmtAcquireDrive((PCHAR)(Drive), Level)
+
+VOID
+FmtReleaseDrive(
+    HANDLE evt
+    );
+
+BOOLEAN
+FmtIsDriveAcquired(
+    PCHAR Drive,
+    CHAR Level
+    );
diff --git a/reactos/drivers/filesystems/udfs/Include/getopt.cpp b/reactos/drivers/filesystems/udfs/Include/getopt.cpp
new file mode 100644 (file)
index 0000000..f03c406
--- /dev/null
@@ -0,0 +1,485 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#include "getopt.h"
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
+
+static enum
+{
+    REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+#define my_index    wcschr
+
+#define my_strtoul  wcstoul
+#define my_strlen   wcslen
+#define my_strncmp  wcsncmp
+#define my_strcpy   wcscpy
+#define my_strcat   wcscat
+#define my_strcmp   wcscmp
+
+/* Handle permutation of arguments.  */
+
+
+void
+getopt_init(optarg_ctx* o) {
+
+    o->optarg = NULL;
+    o->optind = 0;
+    o->optopt = BAD_OPTION;
+    o->opterr = 1;
+}
+
+static void
+exchange (
+    optarg_ctx* o,
+    WCHAR **argv
+    )
+{
+    WCHAR *temp, **first, **last;
+
+    /* Reverse all the elements [first_nonopt, optind) */
+    first = &argv[o->first_nonopt];
+    last  = &argv[o->optind-1];
+    while (first < last) {
+        temp = *first; *first = *last; *last = temp; first++; last--;
+    }
+    /* Put back the options in order */
+    first = &argv[o->first_nonopt];
+    o->first_nonopt += (o->optind - o->last_nonopt);
+    last  = &argv[o->first_nonopt - 1];
+    while (first < last) {
+        temp = *first; *first = *last; *last = temp; first++; last--;
+    }
+
+    /* Put back the non options in order */
+    first = &argv[o->first_nonopt];
+    o->last_nonopt = o->optind;
+    last  = &argv[o->last_nonopt-1];
+    while (first < last) {
+        temp = *first; *first = *last; *last = temp; first++; last--;
+    }
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns `EOF'.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return BAD_OPTION after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return BAD_OPTION.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal(
+    optarg_ctx* o,
+    int argc,
+    WCHAR *const *argv,
+    const WCHAR *optstring,
+    const struct option *longopts,
+    int *longind,
+    int long_only)
+{
+    int option_index;
+
+    o->optarg = 0;
+
+    /* Initialize the internal data when the first call is made.
+       Start processing options with ARGV-element 1 (since ARGV-element 0
+       is the program name); the sequence of previously skipped
+       non-option ARGV-elements is empty.  */
+
+    if (o->optind == 0)
+    {
+        o->first_nonopt = o->last_nonopt = o->optind = 1;
+
+        o->nextchar = NULL;
+
+        /* Determine how to handle the ordering of options and nonoptions.  */
+
+        if (optstring[0] == '-') {
+            ordering = RETURN_IN_ORDER;
+            ++optstring;
+        } else if (optstring[0] == '+') {
+            ordering = REQUIRE_ORDER;
+            ++optstring;
+/*        } else if (getenv ("POSIXLY_CORRECT") != NULL) {
+            ordering = REQUIRE_ORDER;*/
+        } else {
+            ordering = PERMUTE;
+        }
+    }
+
+    if (o->nextchar == NULL || *(o->nextchar) == '\0')
+    {
+        if (ordering == PERMUTE)
+        {
+            /* If we have just processed some options following some non-options,
+               exchange them so that the options come first.  */
+
+            if (o->first_nonopt != o->last_nonopt && o->last_nonopt != o->optind) {
+                exchange (o, (WCHAR **) argv);
+            } else if (o->last_nonopt != o->optind) {
+                o->first_nonopt = o->optind;
+            }
+
+            /* Now skip any additional non-options
+               and extend the range of non-options previously skipped.  */
+
+            while (o->optind < argc
+                   && (argv[o->optind][0] != '-' || argv[o->optind][1] == '\0')
+                  ) {
+                o->optind++;
+            }
+            o->last_nonopt = o->optind;
+        }
+
+        /* Special ARGV-element `--' means premature end of options.
+       Skip it like a null option,
+       then exchange with previous non-options as if it were an option,
+       then skip everything else like a non-option.  */
+
+        if (o->optind != argc && !my_strcmp (argv[o->optind], L"--"))
+        {
+            o->optind++;
+
+            if (o->first_nonopt != o->last_nonopt && o->last_nonopt != o->optind) {
+                exchange (o, (WCHAR **) argv);
+            } else if (o->first_nonopt == o->last_nonopt) {
+                o->first_nonopt = o->optind;
+            }
+            o->last_nonopt = argc;
+
+            o->optind = argc;
+        }
+
+        /* If we have done all the ARGV-elements, stop the scan
+        and back over any non-options that we skipped and permuted.  */
+
+        if (o->optind == argc)
+        {
+            /* Set the next-arg-index to point at the non-options
+               that we previously skipped, so the caller will digest them.  */
+            if (o->first_nonopt != o->last_nonopt)
+                o->optind = o->first_nonopt;
+            return EOF;
+        }
+
+        /* If we have come to a non-option and did not permute it,
+       either stop the scan or describe it to the caller and pass it by.  */
+
+        if ((argv[o->optind][0] != '-' || argv[o->optind][1] == '\0'))
+        {
+            if (ordering == REQUIRE_ORDER)
+                return EOF;
+            o->optarg = argv[o->optind++];
+            return 1;
+        }
+
+         /* We have found another option-ARGV-element.
+        Start decoding its characters.  */
+        o->nextchar = (argv[o->optind] + 1
+            + (longopts != NULL && argv[o->optind][1] == '-'));
+    }
+
+    if (longopts != NULL
+        && ((argv[o->optind][0] == '-'
+         && (argv[o->optind][1] == '-' || long_only))
+        ))
+    {
+        const struct option *p;
+        WCHAR *s = o->nextchar;
+        int exact = 0;
+        int ambig = 0;
+        const struct option *pfound = NULL;
+        int indfound = 0;
+
+        while (*s && *s != '=')
+            s++;
+
+        /* Test all options for either exact match or abbreviated matches.  */
+        for (p = longopts, option_index = 0;
+             p->name;
+             p++, option_index++)
+        if ( (p->val) && (!my_strncmp (p->name, o->nextchar, s - o->nextchar)) )
+        {
+            if (s - o->nextchar == (int)my_strlen (p->name))
+            {
+                /* Exact match found.  */
+                pfound = p;
+                indfound = option_index;
+                exact = 1;
+                break;
+            } else if (pfound == NULL) {
+                /* First nonexact match found.  */
+                pfound = p;
+                indfound = option_index;
+            } else {
+              /* Second nonexact match found.  */
+                ambig = 1;
+            }
+        }
+
+        if (ambig && !exact) {
+            if (o->opterr) {
+                KdPrint(("%ws: option `%s' is ambiguous\n",
+                     argv[0], argv[o->optind]));
+            }
+            o->nextchar += my_strlen (o->nextchar);
+            o->optind++;
+            return BAD_OPTION;
+        }
+
+        if (pfound != NULL)
+        {
+            option_index = indfound;
+            o->optind++;
+            if (*s) {
+                /* Don't test has_arg with >, because some C compilers don't
+               allow it to be used on enums.  */
+                if (pfound->has_arg) {
+                    o->optarg = s + 1;
+                } else {
+                    if (o->opterr) {
+                        if (argv[o->optind - 1][1] == '-') {
+                            /* --option */
+                            KdPrint((
+                                 "%ws: option `--%ws' doesn't allow an argument\n",
+                                 argv[0], pfound->name));
+                        } else {
+                            /* +option or -option */
+                            KdPrint((
+                                 "%ws: option `%c%ws' doesn't allow an argument\n",
+                                 argv[0], argv[o->optind - 1][0], pfound->name));
+                        }
+                    }
+                    o->nextchar += my_strlen (o->nextchar);
+                    return BAD_OPTION;
+                }
+            }
+            else if (pfound->has_arg == 1)
+            {
+                if (o->optind < argc) {
+                    o->optarg = argv[(o->optind)++];
+                } else {
+                    if (o->opterr)
+                        KdPrint(("%ws: option `%ws' requires an argument\n",
+                           argv[0], argv[o->optind - 1]));
+                    o->nextchar += my_strlen (o->nextchar);
+                    return optstring[0] == ':' ? ':' : BAD_OPTION;
+                }
+            }
+            o->nextchar += my_strlen (o->nextchar);
+            if (longind != NULL)
+                *longind = option_index;
+            if (pfound->flag) {
+                *(pfound->flag) = pfound->val;
+                return 0;
+            }
+            return pfound->val;
+        }
+         /* Can't find it as a long option.  If this is not getopt_long_only,
+        or the option starts with '--' or is not a valid short
+        option, then it's an error.
+        Otherwise interpret it as a short option.  */
+        if (!long_only || argv[o->optind][1] == '-'
+            || my_index (optstring, *(o->nextchar)) == NULL)
+        {
+            if (o->opterr)
+            {
+                if (argv[o->optind][1] == '-') {
+                    /* --option */
+                    KdPrint(("%ws: unrecognized option `--%ws'\n",
+                         argv[0], o->nextchar));
+                } else {
+                    /* +option or -option */
+                    KdPrint(("%ws: unrecognized option `%c%ws'\n",
+                         argv[0], argv[o->optind][0], o->nextchar));
+                }
+            }
+            o->nextchar = (WCHAR *) L"";
+            o->optind++;
+            return BAD_OPTION;
+        }
+    }
+
+    /* Look at and handle the next option-character.  */
+
+    {
+        WCHAR c = *(o->nextchar)++;
+        WCHAR *temp = my_index (optstring, c);
+
+        /* Increment `optind' when we start to process its last character.  */
+        if (*(o->nextchar) == '\0')
+          ++(o->optind);
+
+        if (temp == NULL || c == ':')
+        {
+            if (o->opterr)
+            {
+                KdPrint(("%ws: illegal option -- %c\n", argv[0], c));
+            }
+            o->optopt = c;
+            return BAD_OPTION;
+        }
+        if (temp[1] == ':')
+        {
+            if (temp[2] == ':')
+            {
+                /* This is an option that accepts an argument optionally.  */
+                if (*(o->nextchar) != '\0') {
+                    o->optarg = o->nextchar;
+                    o->optind++;
+                } else {
+                    o->optarg = 0;
+                }
+                o->nextchar = NULL;
+            }
+            else
+            {
+                /* This is an option that requires an argument.  */
+                if (*(o->nextchar) != '\0')
+                {
+                    o->optarg = o->nextchar;
+                    /* If we end this ARGV-element by taking the rest as an arg,
+                       we must advance to the next element now.  */
+                    o->optind++;
+                }
+                else if (o->optind == argc)
+                {
+                    if (o->opterr)
+                    {
+                        KdPrint(("%ws: option requires an argument -- %c\n",
+                             argv[0], c));
+                    }
+                    o->optopt = c;
+                    if (optstring[0] == ':') {
+                        c = ':';
+                    } else {
+                        c = BAD_OPTION;
+                    }
+                }
+                else
+                {
+                    /* We already incremented `optind' once;
+                   increment it again when taking next ARGV-elt as argument.  */
+                    o->optarg = argv[o->optind++];
+                }
+                o->nextchar = NULL;
+            }
+        }
+        return c;
+    }
+}
+
+int
+getopt (
+    optarg_ctx* o,
+    int argc,
+    WCHAR *const *argv,
+    const WCHAR *optstring)
+{
+    return _getopt_internal (o, argc, argv, optstring,
+               (const struct option *) 0,
+               (int *) 0,
+               0);
+}
+
+int
+getopt_long (
+    optarg_ctx* o,
+    int argc,
+    WCHAR *const *argv,
+    const WCHAR *options,
+    const struct option *long_options,
+    int *opt_index)
+{
+  return _getopt_internal (o, argc, argv, options, long_options, opt_index, 0);
+}
+
+
+#ifdef  __cplusplus
+}
+#endif
diff --git a/reactos/drivers/filesystems/udfs/Include/getopt.h b/reactos/drivers/filesystems/udfs/Include/getopt.h
new file mode 100644 (file)
index 0000000..d732afa
--- /dev/null
@@ -0,0 +1,142 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifndef _GETOPT_H
+#define _GETOPT_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define BAD_OPTION '\0'
+
+typedef struct _optarg_ctx {
+    /* For communication from `getopt' to the caller.
+       When `getopt' finds an option that takes an argument,
+       the argument value is returned here.
+       Also, when `ordering' is RETURN_IN_ORDER,
+       each non-option ARGV-element is returned here.  */
+
+    WCHAR* optarg;
+
+    /* Index in ARGV of the next element to be scanned.
+       This is used for communication to and from the caller
+       and for communication between successive calls to `getopt'.
+
+       On entry to `getopt', zero means this is the first call; initialize.
+
+       When `getopt' returns EOF, this is the index of the first of the
+       non-option elements that the caller should itself scan.
+
+       Otherwise, `optind' communicates from one call to the next
+       how much of ARGV has been scanned so far.  */
+
+    int optind;
+
+    /* The next char to be scanned in the option-element
+       in which the last option character we returned was found.
+       This allows us to pick up the scan where we left off.
+
+       If this is zero, or a null string, it means resume the scan
+       by advancing to the next ARGV-element.  */
+
+    WCHAR *nextchar;
+
+    /* Callers store zero here to inhibit the error message
+       for unrecognized options.  */
+
+    int opterr;
+
+    /* Set to an option character which was unrecognized.
+       This must be initialized on some systems to avoid linking in the
+       system's own getopt implementation.  */
+
+    int optopt;
+
+    /* Describe the part of ARGV that contains non-options that have
+       been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+       `last_nonopt' is the index after the last of them.  */
+
+    int first_nonopt;
+    int last_nonopt;
+
+    /* Exchange two adjacent subsequences of ARGV.
+       One subsequence is elements [first_nonopt,last_nonopt)
+       which contains all the non-options that have been skipped so far.
+       The other is elements [last_nonopt,optind), which contains all
+       the options processed since those non-options were skipped.
+
+       `first_nonopt' and `last_nonopt' are relocated so that they describe
+       the new indices of the non-options in ARGV after they are moved.
+
+       To perform the swap, we first reverse the order of all elements. So
+       all options now come before all non options, but they are in the
+       wrong order. So we put back the options and non options in original
+       order by reversing them again. For example:
+           original input:      a b c -x -y
+           reverse all:         -y -x c b a
+           reverse options:     -x -y c b a
+           reverse non options: -x -y a b c
+    */
+
+} optarg_ctx, *P_optarg_ctx;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument          (or 0) if the option does not take an argument,
+   required_argument    (or 1) if the option requires an argument,
+   optional_argument    (or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+  WCHAR *name;
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+extern void getopt_init(optarg_ctx* o);
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define no_argument             0
+#define required_argument       1
+#define optional_argument       2
+
+extern int getopt (optarg_ctx* o, int argc, WCHAR *const *argv, const WCHAR *shortopts);
+extern int getopt_long (optarg_ctx* o, int argc, WCHAR *const *argv, const WCHAR *shortopts,
+                        const struct option *longopts, int *longind);
+extern int getopt_long_only (optarg_ctx* o, int argc, WCHAR *const *argv,
+                             const WCHAR *shortopts,
+                             const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (optarg_ctx* o, int argc, WCHAR *const *argv,
+                             const WCHAR *shortopts,
+                             const struct option *longopts, int *longind,
+                             int long_only);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/reactos/drivers/filesystems/udfs/Include/key_lib.cpp b/reactos/drivers/filesystems/udfs/Include/key_lib.cpp
new file mode 100644 (file)
index 0000000..7496150
--- /dev/null
@@ -0,0 +1,101 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+static const char XPEHb[] = "zfvbgt^&*()aq,lpwdenjsxnygv!@yhuhb#$%chimuokbr";
+
+UDF_FibonachiNum(
+    int n,
+    int* f
+    )
+{
+    int a=0xff557788;
+    int i;
+    // do something
+    n <<= 8;
+    for(i=0; i<n; i = i++) {
+        a = ((a+i)*2) ^ ((a+n) * (XPEHb[i % (sizeof(XPEHb)-1)]) & 0xfffffffe) + 1;
+        if(i*2 >= n) {
+            n >>= 4;
+            (*f) = (*f) ^ (a+n);
+            n >>= 1;
+            a = n & a;
+        }
+    }
+    n >>= 3;
+    // if(n < 2)
+    if(!(n & ~1))
+        return 1;
+    n--;
+    if(!(n+1))
+        return 1;
+    a = UDF_FibonachiNum(n, f);
+    return UDF_FibonachiNum(n-1, f) + a;
+}
+
+void
+UDF_build_long_key(
+    char* buffer,
+    int blen,
+    char* key_str,
+    int klen
+    )
+{
+    int i, k, j;
+    int r[32];
+    int* tmp = (int*)buffer;
+    int f, fn;
+
+    memcpy(buffer, key_str, klen);
+    for(i=0; i<klen/4; i++) {
+        r[i%32] = tmp[i];
+    }
+    f = 0xf4acb89e;
+    for(k=0, fn=1, j=0; i<blen/4; i++) {
+        if(!fn) {
+            tmp[i] = tmp[k%(klen/4)];
+            fn = UDF_FibonachiNum(k, &f);
+            k++;
+            continue;
+        }
+        if(i>=blen/4)
+            break;
+        r[j%(klen/4)] = (int32)( ((int64)r[j%(klen/4)] * 0x8088405 + 1) >> 3 );
+        tmp[i] = r[j%(klen/4)] ^ f;
+        j++;
+        fn--;
+    }
+} // end UDF_build_long_key()
+
+
+void
+UDF_build_hash_by_key(
+    char* longkey_buffer,
+    int   longkey_len,
+    char* key_hash,
+    char* key_str
+    )
+{
+    UDF_MD5_CTX context;
+    char key1[16];
+    int m;
+
+    UDF_build_long_key(longkey_buffer, longkey_len, key_str, 16);
+    UDF_MD5Init(&context);
+    UDF_MD5Update(&context, (PUCHAR)longkey_buffer, longkey_len);
+    UDF_MD5Pad (&context);
+    UDF_MD5Final((PUCHAR)key_hash, &context);
+    memcpy(key1, key_hash, 16);
+    for(m = 0; m<113; m++) {
+        UDF_build_long_key(longkey_buffer, longkey_len, key_hash, 16);
+        UDF_MD5Init(&context);
+        UDF_MD5Update(&context, (PUCHAR)longkey_buffer, longkey_len);
+        UDF_MD5Pad (&context);
+        UDF_MD5Final((PUCHAR)key_hash, &context);
+    }
+    for(m=0; m<16; m++) {
+        key_hash[m] = key_hash[m] ^ key1[m];
+    }
+} // end UDF_build_hash_by_key()
+
diff --git a/reactos/drivers/filesystems/udfs/Include/key_lib.h b/reactos/drivers/filesystems/udfs/Include/key_lib.h
new file mode 100644 (file)
index 0000000..96fbde5
--- /dev/null
@@ -0,0 +1,25 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#include "platform.h"
+#include "md5.h"
+
+#define UDF_LONG_KEY_SIZE  1024
+
+extern void
+UDF_build_long_key(
+    char* buffer,
+    int blen,
+    char* key_str,
+    int klen
+    );
+
+extern void
+UDF_build_hash_by_key(
+    char* longkey_buffer,
+    int   longkey_len,
+    char* key_hash,
+    char* key_str
+    );
diff --git a/reactos/drivers/filesystems/udfs/Include/keys.cpp.tpl b/reactos/drivers/filesystems/udfs/Include/keys.cpp.tpl
new file mode 100644 (file)
index 0000000..8840e17
--- /dev/null
@@ -0,0 +1,589 @@
+{0x464eb272,0x9f4d726f,0x40f95d9c,0x3987ae09},
+{0x456423b2,0x6b084fb2,0x779f232e,0x3433bcb2},
+{0x120b2a5f,0xa015659c,0x37d3a35b,0xedddc7c6},
+{0x58eb88c0,0x93b4d904,0x39289e8c,0x485c18d0},
+{0x05da8341,0x1a37a08a,0xab5b9093,0xc1ad8dd0},
+{0x9f157c9c,0xeefec917,0x14f2f336,0x717fcc0c},
+{0x6b7a8089,0xa2097489,0x45dbe485,0x37d0f63b},
+{0xe28ba237,0xb97e5d70,0xb07696bc,0xa506a664},
+{0xd19ad8eb,0x7a0f236a,0xf80290c1,0x71f2b5b2},
+{0x2b0ec7d5,0x88271955,0xa90f3199,0x9dc098da},
+{0x5b0fcd3e,0x5778354a,0xda5e2509,0xf396b58b},
+{0xdf75eeeb,0xba02b001,0x68c29e6f,0xc5514d9c},
+{0x7c6ea336,0x41cbcd58,0xb777e433,0x664ab6d1},
+{0x960026ce,0x9cbd1c87,0xfa1a7818,0x84c673b6},
+{0x2ac852ac,0x8eaa9681,0x6819f875,0x6fc551a9},
+{0xc518549b,0x7a0a8230,0x5a1bfb84,0xa46f9027},
+{0x9e5eaa05,0xb9cdb6c6,0xccd325d7,0xf4d9c68f},
+{0x41b3b128,0xc3c8ce01,0x5f42b5e3,0x91b0d7e6},
+{0x0db18065,0x7e263df0,0xce72309b,0xcd15c548},
+{0x8fa12a15,0xf034c880,0x462828da,0x30720e25},
+{0xe4580867,0xc4323a04,0x2aad1d4a,0xabb5f2ae},
+{0x2d409ac0,0xca426d96,0xb6cff690,0x7ed609b1},
+{0x846bc82a,0xa2c5220b,0xfc8f9e6e,0x90cbb453},
+{0xe4461b74,0x9ebbf4ab,0x35d634e6,0xc026a6e8},
+{0x6f1aad49,0xf6812aef,0x0ee812a4,0xf878c9fc},
+{0xf5f1e6c0,0xffb384c5,0xea5fc9ab,0x4489c71c},
+{0x0a992ebb,0xd335a4ef,0x7d804a9e,0xcb7712fe},
+{0x27973f49,0x98b65183,0xecc6eb21,0xd7562406},
+{0xde9aa2fe,0x0a8ba7a6,0x762f5c9e,0x85dfc7e1},
+{0x9eb2a02a,0x08b8013e,0x58414587,0x14075bd0},
+{0xd6d2aa52,0xa5776692,0xd654a793,0xf8b2cd1e},
+{0x39acbf3c,0x91cfaedf,0xcda41b5a,0xbd1f43d9},
+{0xcb4e4068,0xfde0605e,0xa200dfa8,0x55a179d7},
+{0x505783e6,0xccd8c3bf,0x6f533151,0xb70b4ba9},
+{0x5dc7eeac,0xc3170129,0x942820e0,0x39663808},
+{0xc42d92cb,0xd32fc416,0x9b0e7e03,0x1d06b84c},
+{0x03f18479,0x7415b991,0x45fdb32f,0xfad21e67},
+{0x3bbcc977,0xcdceddc3,0x3087028f,0x3931f927},
+{0x3f600fc9,0x117dd904,0x53517eea,0x0f9063d1},
+{0xa23d715c,0x0da00448,0x7b397ad1,0x9fd7dd2a},
+{0x0d663599,0x4ff3e55d,0xe699dd5f,0x67d8cda1},
+{0x1fc05d79,0x5ef1a023,0x3541c6ca,0x5c087e48},
+{0x4bcbadc0,0xf2dafc5d,0x36ae4de2,0x3a360d1d},
+{0xae6a5788,0x1af7450b,0x10016900,0x6dca6aa3},
+{0xe8f6ff62,0xd2d9648c,0x3a914a56,0x887e6f02},
+{0x94a20036,0xd2ad657d,0x131df7d6,0xda27739d},
+{0x3ad80c90,0xc88d6b6a,0xed0c5936,0xb7848cff},
+{0xe85b07f9,0x43ef69a7,0x0649cac1,0x3724d61c},
+{0x7a6b0657,0x0fbb8c0d,0xe58e7262,0xf91c8036},
+{0x712b77b4,0xe4b1b0be,0xeb63ffd5,0x92bf033c},
+{0x54f1a982,0x83b6eb99,0x0b867758,0x2f213a25},
+{0x4e8c8976,0x1164dcac,0x53fbe278,0xad869afd},
+{0x05b566d7,0x467e202a,0xde861a33,0x73cd0c01},
+{0x50be1f0d,0xaf750eb0,0x55b8f755,0x5acb4ee7},
+{0x6f50daef,0x8537a233,0xb66ee044,0x2826c9a9},
+{0x942ddb0b,0xf5cb9067,0x78b2d2df,0x247d59b3},
+{0x90c659cf,0x444b27f5,0xe594e04a,0x4bb89ef2},
+{0x166e744e,0xeb9a0b8e,0x5ed79141,0x16c03653},
+{0x9da99fe5,0x1aef04a2,0x166a6d89,0x20fe85cc},
+{0x659a562e,0xc6a1d311,0x27d436b8,0xdf880426},
+{0x3c01541a,0x4dcdedf2,0x26bf4d05,0x9d7b80a1},
+{0x547cce62,0xdffbe77d,0xbc465468,0xab8813d5},
+{0xe8e5fe73,0x0a99255e,0x0f1848ac,0x9249c412},
+{0xb7c8f524,0x14016b68,0x92bf5ba9,0xd9860a34},
+{0xf3987bec,0xabc1d48f,0xc2295390,0x920807fd},
+{0x21f31bc9,0xdd912f06,0x04d4b523,0x511c166a},
+{0xd314e200,0x122253bc,0x586860a4,0xbdefecb0},
+{0x81e3b97f,0x5a34322e,0x901f12da,0x96ac5962},
+{0xbe70be25,0x9708c176,0x40515add,0x6670a8c6},
+{0x5a55b6bf,0xc41d077b,0x2be20a8b,0xa9346d1d},
+{0xf0940335,0x2dba5988,0x2b8de508,0xf10f90c4},
+{0x0858b635,0x98de0a2f,0xeb8826ee,0x99cccb5a},
+{0xf5970be7,0xa6206cae,0xa37967e4,0x7e3bdc8a},
+{0x620fd372,0x073b8288,0xeab77455,0xcfac4b96},
+{0x5a06daad,0x4d4f13f9,0x8815aa2d,0x418dba52},
+{0x5592b759,0xc54bf215,0x4d77971f,0xa569eec6},
+{0x6870ac5d,0xe715f4e0,0x188dbd7f,0xa0382fe1},
+{0xe438b05d,0x3743cffb,0x248b2ef1,0x2f37a8e7},
+{0xd075a482,0x787d34f6,0x999fc5a6,0x72c85a6e},
+{0x8cd0f999,0x67df4221,0x5aed7b04,0xc1887d1b},
+{0x8c983d3e,0x659ea055,0xec19849b,0x6da93a70},
+{0xfa69945f,0xa01e9036,0x6d1aba4f,0x6e001f63},
+{0x2f4cac40,0x004cfb9e,0x90c69b60,0xf4b4e109},
+{0xea15c026,0x4020cba9,0x935c4015,0xcd05f40e},
+{0x02e36239,0x9e05673a,0x6ee41e8c,0xd0cda541},
+{0x73a11589,0x5353d35e,0xe5bcb258,0x5fdea079},
+{0x97399ffd,0x05f9dc63,0x726e96c1,0xdcb01c47},
+{0xda84fbbc,0xf2c3c339,0xc48b9dc3,0xa68c7944},
+{0x4ab14c3a,0x47fe735d,0x4655bc4e,0xbb012871},
+{0x59fe1d5e,0x3f384cb1,0x4c377278,0x1850c1b5},
+{0x894d4e2e,0xb10e74b4,0x5e66dfb6,0x11f2f75c},
+{0xea4c6df5,0x95977aa6,0x442ed4bf,0x00767341},
+{0x9d8de9e3,0xad5c1bff,0x7745fff8,0x84d8282d},
+{0x676ac7b5,0x7b86dcd8,0x04631a2e,0x87a89cbb},
+{0x1d5ff8bc,0x13867c85,0x744f5d2f,0x776b6be7},
+{0x2de75ec7,0xf934c55b,0x338e7ef9,0x7c2a4174},
+{0x2225c2da,0x29fe9067,0x49351267,0x74d2831e},
+{0x661146b1,0x98a6751f,0xaf2e7c12,0xfd68d646},
+{0xc355f1d4,0xb5969617,0xdafa73d5,0xc6d36593},
+{0xfaa00891,0xa50a94d5,0xa859ebf3,0x90c6b97d},
+{0xdf2655ad,0xa48b57c5,0xc98e0d75,0xb1eb6547},
+{0xedc5fcf9,0x94bb1c9e,0xd9a457bd,0xdaa1f872},
+{0x04610e08,0x39a2ae50,0xeeb1ef12,0x5e3c0b85},
+{0x80125cae,0x375dd9ab,0x39795460,0x8ef0b2a6},
+{0x7ba2a83d,0x3e1c749a,0x50441a9e,0xf3d9286b},
+{0x22b80ffd,0x5a90460b,0x37304e96,0x100d0c16},
+{0xfc036a30,0xf2f3e782,0x1a1c52e0,0x818e62e3},
+{0x8fb2a8f0,0x78180dd5,0xf0146702,0x25e00c6c},
+{0xec8df538,0x5c116a43,0xec5ea158,0xfdb3c321},
+{0xc1e5afd7,0x63697a31,0x1e851111,0x0527619a},
+{0xe2990e8a,0xbf60a048,0x3f4b4881,0xb6f2d454},
+{0xe81da5b7,0x1d07e924,0x466d4108,0xb92c1ddb},
+{0xba4b51c5,0xb59f9676,0x9f6dca34,0x5014ff20},
+{0xdff0815b,0xba3359a2,0x290a931e,0x6afe9b4d},
+{0x488cead2,0xb5eba54c,0xab40db01,0x63ddaeb7},
+{0xb003cb57,0x3d0aa6ae,0x163fb5fd,0x2d1e180f},
+{0x8a661121,0x6fdcee1e,0x1d523b8f,0x04b6fb93},
+{0xba0611da,0x35b5cb6e,0x104a28bf,0x14816580},
+{0x1646b6c1,0x821ce88e,0xf5dcb33a,0xa502e55c},
+{0x943a0578,0x13a11f1d,0xb88506e0,0x2103d157},
+{0x99f2bd0a,0xe4557ea2,0x0607eb79,0x7661c9b7},
+{0x8e107dd4,0xec16b306,0xaeeb6102,0x5bed2e1c},
+{0xa0a91efa,0x373cf627,0xfeff21f0,0x15a26e9f},
+{0xa65100d1,0x0c1f1ea1,0x16473e4d,0xed2cd7ba},
+{0xb24fea09,0x18e8d920,0x49a53cac,0xf6854d17},
+{0xb5614dea,0x94e20a25,0x6b7233e8,0x1d9c3206},
+{0xf4a92d75,0x5f85c883,0xab122f23,0x437ca5d0},
+{0x374dd522,0xaac5ad1a,0x38f909f6,0xcc12fee2},
+{0xc2a96679,0xc0bb18fb,0xcd6d815c,0xbe637fe2},
+{0x652ce71f,0xe9425870,0xa42108df,0x68b4ccf0},
+{0xe5bbe5c4,0xfd090753,0xdac4efd2,0x5ea56477},
+{0x8f67d8a0,0x8fd61beb,0x0be2ff50,0x77078ab9},
+{0x71b68a44,0x75b34d51,0x885fd1d0,0x1b3f28ab},
+{0x670800ed,0x2802d7d8,0x23e22f3e,0xfdf3fb80},
+{0xcf519664,0xd9a4d453,0xd2623c20,0xa9a80f2d},
+{0x5f7af403,0xf859e86a,0xc7098674,0x8e46ebb8},
+{0x188c447b,0x94c207aa,0xd493db27,0x67f11959},
+{0x39f6f669,0xe07725e8,0x11e48861,0x6a2e8fac},
+{0xce335586,0xc6516c67,0xf65ef1c4,0xe9069f25},
+{0x75b2f286,0x0c8c4720,0xd63d60ea,0xe4340b83},
+{0x7d98ea1e,0x9da042ba,0x00a7c496,0x973aeaef},
+{0x8586cbb6,0x6c621b59,0xb5786657,0x143dd33c},
+{0x8c5da8f3,0x4c5aa120,0xc446424a,0x346681cf},
+{0x3df341bd,0xa9bbf625,0xcc0d6b59,0x5bce0859},
+{0x1cf1de06,0xc423eb66,0xe2a84cc1,0x8aa424e3},
+{0x8ab60890,0x2a032b4c,0xb564278f,0xb6eff9d4},
+{0x85e25a8f,0xfc8e7dc7,0xb94c8d7e,0xbd92faaa},
+{0x9849a0b5,0x9a6c8a7a,0x60b658e6,0x73c26c6d},
+{0xc6508f66,0xf39b1a2b,0xe9b4b7d5,0x42e524df},
+{0x98b3efb4,0x0515335d,0x56ea9c83,0xb09d656e},
+{0xe8390256,0x127e9239,0x0df5c7f7,0x2aaf968c},
+{0x62e426fb,0xf23ae4e1,0x23cc1adf,0x903c2634},
+{0x13a2b181,0x28a68411,0x033514ce,0x6f2d392c},
+{0x96d0993c,0xc95e6371,0xa3ecb3d7,0x32c580c2},
+{0xdbdd9789,0x4b063cf0,0xd3ca705d,0xff1dde9e},
+{0x744210fe,0xb47cb775,0xe9209529,0x5d92fb9d},
+{0x576aa312,0x4b7fde61,0xba2b3590,0xe1919c0b},
+{0x8c414c99,0x8d2f9965,0x70e75b2e,0x201daf0c},
+{0xe74c5ce2,0xe0730812,0x32ac229b,0x8b574aab},
+{0x6a27385e,0xf7e62ce0,0x996569f5,0xca9d3768},
+{0x51583907,0x2375d2d2,0x511db2d8,0xed73b351},
+{0xc2181bce,0xded144b4,0x4121147a,0xfc367633},
+{0xaa9dac85,0x25346819,0x3077443f,0x54c0227c},
+{0x2fefcbd5,0x74ce5196,0x96971fc5,0x6c8f60ac},
+{0xff990570,0xcc61f389,0x3fd1992c,0xd0c617e7},
+{0x67a4f115,0x12d1de80,0x13d0a638,0x39616006},
+{0xd9ce36a8,0x18818b09,0x3e12c13b,0xb941cefe},
+{0xcc118030,0xff2b39f9,0x9ec14ffb,0x75be156a},
+{0x1124525b,0x507b707e,0xb2c2f2ab,0x7fd1545e},
+{0x222288f9,0xc44b221e,0xffd6cbd0,0xb128a234},
+{0xe71aa36b,0x35b1b1a1,0x040ca92d,0x5f33f73f},
+{0x4869432d,0x268e6b9d,0x6151a2c3,0x9cf7b4f2},
+{0x38ff5534,0x75588fd1,0x52502688,0x9d516413},
+{0xf64add9b,0x1dddd827,0x88fea8ad,0xa2d1af76},
+{0x0fe4a7e7,0xd6fe3fc2,0xba6d6256,0xa4fd8553},
+{0x285bd0aa,0x9f53a7b8,0x0302a4fe,0x12ba4a22},
+{0xf0a02afe,0x5669141a,0x05958a39,0xe87f04ea},
+{0xdac350d0,0xd29fb016,0x5c5f0b02,0x01f143b2},
+{0x4d20fe77,0xadcbb181,0xc0f04454,0x64b2be37},
+{0xfe0212a7,0x718abe5e,0x98061ae2,0x0dd9e431},
+{0x191a152f,0x87f27de9,0xd054af43,0x00d6b04d},
+{0xc0735210,0x0bd58b3f,0x96ac6912,0x2eb53fcd},
+{0x796f04fa,0xd2689737,0xddc044ff,0x508cb995},
+{0x733e1ee7,0xf579535e,0x9ae30c09,0x1ee0f7e9},
+{0x627b1ebf,0x1604bd39,0x75ffe5f5,0x0c8ca8f1},
+{0x11d7f6fd,0xe86e800b,0x9339f931,0x9798ad9d},
+{0xed7bd57d,0x0db9e1c5,0x2df8a441,0x4a4aab0c},
+{0x69822c06,0xafd7902e,0xb5f897cd,0x2fefbc9d},
+{0x1ae2a0a3,0x71413064,0x53df291b,0x5579b863},
+{0xfdd3de57,0x63d05fd0,0x9fa32952,0x9b84c9c0},
+{0xebecac20,0xbf9f67cb,0x61210e29,0x2d110b22},
+{0x5e1aa86b,0xf928b1bb,0xc43dc3f0,0x5e7a53ca},
+{0x6aeb61c7,0x30acacaa,0x0a758d2f,0x7761a984},
+{0xce30d965,0x4a288c7d,0x7fe3d287,0x805912b1},
+{0x8201f728,0x690c296c,0x41e25b06,0x6ef30ed1},
+{0xd18879df,0x901a3eb3,0xb4e2e516,0x6a25ef09},
+{0x16dea57b,0x874d54b7,0xe7f33a53,0x803701c3},
+{0x16acef19,0xfbe1905c,0xd412145a,0xf25ac334},
+{0x6037cdfc,0x6f33a11b,0x145d5f39,0x5413eeda},
+{0x5aa2bc9f,0xa19c6a1d,0xd6389f34,0x2dd08f8f},
+{0xd6bb0e57,0x148bc047,0x0ba7bca1,0xf0f96f47},
+{0x6a6f0b8d,0x9f713a8d,0x080c8048,0x8fd9d3c5},
+{0x0541a5cb,0x78cebc1d,0xcbbac10d,0xecb49da3},
+{0x2648b918,0x05cf1b76,0xa71b29de,0x4cd4bd85},
+{0x8aca0fef,0x882360fe,0x574f3705,0xffab6346},
+{0xe27847e3,0x4c840db1,0x4cb1ad0d,0xa1502e7f},
+{0x26f3dbef,0xb8586678,0x6ac33e62,0xa79d4883},
+{0x5cf8424b,0xa8d5bdd7,0xdf8e2aff,0x03c2452b},
+{0x04a4e58c,0x586ea473,0xac19957b,0x3cd1808f},
+{0x2276c1ae,0x0f1672e8,0x6ccccefa,0xb474d276},
+{0xca4b83aa,0x5ca07ca6,0x7bad899f,0xcb9cd680},
+{0xaaa3c07a,0x52028a10,0x9921d96c,0xd606e704},
+{0xf7872f1f,0xaf05198d,0x57349b0b,0x7b8bb956},
+{0xf04908e0,0x8f7d2b71,0xcd8689b7,0x08994cb9},
+{0x67be9e79,0x959f2850,0xdfa2ea88,0x2d34c458},
+{0x51066f0f,0x0ecf8473,0x442592e0,0x2a208172},
+{0xb1443065,0xcb4b6c99,0x08fbe6db,0x2dc08b9b},
+{0x68b653df,0x3597e82c,0xb66feb5f,0x6f338761},
+{0x3f660aae,0x121166ba,0xd365615e,0x495b3451},
+{0xe20162e5,0xb5e6c7f3,0x53205114,0x1dd3aa7f},
+{0x6298b11b,0xbb89ed63,0x2d5103e8,0x4fa81473},
+{0xa3d1e970,0x7d4c2764,0x8b8c3d1c,0x8092e54a},
+{0x127eae63,0xacb401d8,0xcc2534f2,0x82678387},
+{0xfead8828,0xd383c70c,0xb01e6836,0x0956c3d6},
+{0x79cc0594,0xb15be42c,0x7f80de1f,0x949636be},
+{0xee08f04d,0x71733158,0x59a04640,0x3efe92c9},
+{0x7c40cc35,0x80211f91,0xe16f901d,0x1664733f},
+{0x4243fc5b,0xf59972ad,0xc2b2d815,0xd4ec83e0},
+{0xd0cce67b,0xc9ed8a0b,0x6938f254,0x26d8a0c6},
+{0xdf14738a,0x22793292,0xca1b8f93,0x5678362f},
+{0x0802182d,0x7c924a03,0xfe99f175,0x15272607},
+{0xc07a61dc,0x383e9160,0x4cf2de36,0xc4112b3b},
+{0x403e1c63,0xd95077ad,0xf70d08ab,0x724e9745},
+{0xf6598de8,0xc024e2b9,0x3ab423f4,0x49238fa9},
+{0xe8869cb8,0xfd517256,0x6c26c298,0x420a6993},
+{0xe9435dbb,0x7ad6419b,0xfa941963,0x3c14b6d6},
+{0x771916a1,0x48ae53cd,0x7d9bd148,0xa2116f9e},
+{0x717b6010,0x08d2ed76,0x7ab952c4,0x2300bf03},
+{0x670d8997,0x09e23cdb,0xeff00f50,0x1698ffad},
+{0xfcb0552c,0x1ad81994,0x643e8022,0xa6a6b588},
+{0x792f05fe,0x10c4910d,0xfcc6d591,0xe8d946aa},
+{0xfa26c441,0xda604668,0x6eaf7282,0x06a523b4},
+{0x534d6d76,0x7c08ddd1,0xdc0b23e5,0x69c7a581},
+{0x308dbe91,0x516877f5,0xe16cb6e6,0xe7947f22},
+{0x677b572b,0x89a23727,0xff1e80f3,0xb5fb00c6},
+{0x9831a920,0x8352bd61,0x79e2867d,0x961d16f3},
+{0x49681542,0xde5393c5,0x8e64217d,0xa4787fcc},
+{0xa5a6f59e,0xeb8826ab,0xfe76dc57,0x3c91e330},
+{0x11b4ff07,0x3207b417,0x4e3a90ff,0xced4c105},
+{0x055f738b,0xd090f472,0x2793925e,0x069c3c9d},
+{0x34895169,0x969a4bac,0x8152a1ec,0x7a429a21},
+{0xabb398b9,0xd1b8b55b,0x2f27435a,0x3b35827e},
+{0x1e5395c7,0xb2f1e9fb,0xd6be7903,0xb139b803},
+{0x0ced7375,0x43f670c1,0x8490f305,0xf953c4ee},
+{0x98ea2ac8,0xed9c2790,0x688551f7,0x88677401},
+{0x6d19e99a,0x17ebf706,0x63e71abb,0x5150811e},
+{0x16ee26fd,0x3cae3d22,0x8bf06d71,0xbdaf50b1},
+{0xd737dfd3,0x6bf72882,0x22455b57,0x6da57325},
+{0x5e062082,0xc8fcf42d,0x7050da6d,0x5ee62bc1},
+{0x762f7783,0xd7f0d368,0x5a424857,0x7f371f3d},
+{0x0c9298a1,0x4685bc48,0x625f5e47,0x74b8c5d7},
+{0xe0157161,0x8c82749c,0x38d25bd2,0x82740065},
+{0x6639d77d,0x3dcc6db6,0x5677ed3e,0xc92f1f5b},
+{0x4e4ffe36,0xd09f9e04,0x35cbaecc,0x635f0f29},
+{0xf27a1827,0x35021b69,0x0b2fec9b,0x3832c35b},
+{0x9370fa61,0x648e4484,0x874a687a,0xff15f1fa},
+{0x6552b060,0xe1eea13c,0x79a81141,0x125a731b},
+{0xcf74e28c,0x361d99cf,0x735ad0d7,0x17781338},
+{0x64c55a26,0x8cf2b57f,0xcffb0eed,0xd44b664b},
+{0x897dbf3e,0xa73d5b3f,0x606eba0b,0x7fea83eb},
+{0xa6cfa45a,0x8e19869e,0xb35b4a59,0xda9790f0},
+{0x5381db83,0xf3e06cca,0xceb51e21,0x806546a5},
+{0x7079e3c7,0x7081515b,0x5d0f2805,0x42077d2e},
+{0x9ebbc897,0x13dea72b,0xe7520b89,0xa0f70f23},
+{0xdc8d587f,0x1563c103,0x752ef3ee,0x3a8aa821},
+{0x8587cf23,0x1a160e5c,0x01a29306,0x8c84e4df},
+{0xb4ef90bd,0x896818ac,0xf6320f47,0xe584a06e},
+{0x5edc16f9,0xda75c31f,0xd73d791f,0x08fc05fb},
+{0x7d9676a7,0x48483537,0x87377025,0xd477e615},
+{0xf9648730,0xbfc1f99a,0xf84247ee,0xf3fbbdd6},
+{0xce336727,0xd9fbc28b,0x173622e8,0xe50427b0},
+{0xb22da76a,0x2f56a7b5,0x9c4a5304,0x26b61345},
+{0x12b2e9f7,0xd91b9ee3,0xc50c580b,0x11bfbf8e},
+{0x5b68aca6,0x9f9c45cc,0x4226003c,0x5033387f},
+{0xcc0b7db1,0x0cbd30ef,0x040fbb96,0xff92790f},
+{0xd8441e4b,0x506feedd,0xf0ef7ef6,0x5278dac5},
+{0xa586b239,0x9057d034,0x045a10d4,0xff0a4501},
+{0x44c84aca,0x72c7e534,0x9d8b762e,0x09ce7080},
+{0xb19f89f4,0x64807b1b,0x5fc256f5,0x484beaed},
+{0xdeee7e78,0xf7953521,0x5ab0d38a,0xd9c5ccf2},
+{0x2752ba06,0xb149df6a,0xa86bdf71,0x98177806},
+{0x0b165963,0x80c9e332,0x45b05eb9,0x56436678},
+{0x07db7854,0xafbfa56c,0xd598aef9,0x20291690},
+{0x34105580,0x3ebff180,0xb54f0d9f,0x5aac4179},
+{0x9216b3c1,0x0ea2ccc3,0x15e72dba,0x8109567c},
+{0xf3f71644,0x8300bfa8,0xc7762650,0x52cffa43},
+{0xf0e3fcd9,0x0692f957,0x29cb6333,0x6551e83e},
+{0xaf299261,0x0fd8ad80,0x953d045a,0xdcdc0dd8},
+{0xe4e0e616,0x5697b667,0x739cdf50,0x1632e015},
+{0xa463afb0,0x00037812,0xe0ff4e3b,0x7f9370d4},
+{0x8d0dcddd,0xa0222788,0x75a07e11,0x928890db},
+{0xfae0d7f6,0x547c9f6c,0xcaa46153,0x26151c95},
+{0xf09671ce,0x39c5ad01,0x503458f5,0x55c989c9},
+{0xa0be3f26,0x8e164850,0xf62f453b,0x15763688},
+{0x6277b34d,0x5cf05538,0xf98f5180,0xaac7a458},
+{0x194be347,0xe9652177,0x4c76c864,0x43b90beb},
+{0x04334387,0x6c9a1c64,0xb478b652,0xa68a0530},
+{0xe0b5287c,0xdd5fa3c9,0x18ac0290,0x6355f990},
+{0xfb975657,0x11030bd2,0xf873a64b,0xe908982b},
+{0x0c039dcc,0xb4a27dcd,0x7f91df01,0x6ca660cf},
+{0x4a5f70c7,0x08d66dad,0xbaeb303d,0xeaf6ac62},
+{0x6134df3f,0x4346c32d,0x0ccef492,0x80d58162},
+{0x3f9e9cb8,0xa3008f54,0xf7022502,0x096aa2db},
+{0x09643405,0x0bef72e1,0x7a0161e3,0x02b6800d},
+{0x4a9fd7b2,0x2ff2c6e7,0xb0e0f0d6,0x22c5dd5e},
+{0x065c8abe,0x3a54cf26,0x08376d5d,0xd7cdfe40},
+{0xddde7842,0xf5ac25cd,0x2c3a8ba3,0xd8475b2e},
+{0xcb7569f8,0x91c35be9,0x4f235518,0x01922f3b},
+{0x37d9967b,0xfec674e7,0x37ba068d,0xbe1e5473},
+{0xf015ccfa,0x273f9622,0x5b01fa82,0x57b49d65},
+{0xcedfafa7,0xf839a339,0x39de9cb8,0x92af53c7},
+{0xf3a0db2a,0xe94cfc32,0x97d7ba1e,0x63b49741},
+{0xb2b87d08,0x1f1f6080,0xfd768ea4,0x4a975140},
+{0xd81d6db5,0xc8963e38,0x16410bb1,0x2ea27c76},
+{0x8a93e2f6,0x62fbb98e,0x56f90e07,0xbe9e0de9},
+{0x38e10de8,0x39b0022d,0x912eb927,0x8932e981},
+{0x26342052,0xd9b8fc21,0xefb02a6c,0xc904b8aa},
+{0xde4a82f1,0x3bb922f5,0x9b7d98b1,0xa94ba85b},
+{0xacd0ce2c,0xdd191a60,0x0ced9791,0x2ca62c1e},
+{0xc29af305,0xe13d427b,0x37dbd054,0x4c9e741d},
+{0xf835ce44,0xaf77c79a,0x888dd7f4,0x2488e20c},
+{0x08790953,0xe1e8b06a,0x5779d964,0x231b9d94},
+{0xd09a2d81,0x4c3bf9c8,0xda6a82c5,0x1ed5874c},
+{0x264cfcca,0xa15fd61f,0x44a36e1e,0xbff8e65a},
+{0xac7f9e1c,0x93a018cd,0xf946989e,0xdf35f7bd},
+{0xe6b78c52,0x1ab4250b,0xaf864921,0xb2d6cbff},
+{0xc1d932c6,0xd21fc917,0xe80769ea,0x547f1728},
+{0x446a0ef9,0xcd05936a,0xd5b01469,0xb217ad15},
+{0x5b6d04c3,0x4062fa77,0xac7e474f,0x14183152},
+{0x18715a09,0xb425c049,0x271a175e,0xaba13a20},
+{0xe5784f5a,0x06a69f91,0x55c31430,0x1d3c1e03},
+{0x89d90d35,0x9799d79d,0x1aba6e3e,0x5f4820cb},
+{0xc10a24ab,0xbe37d72e,0x4470cb4a,0x238cb818},
+{0xb66ab610,0xa32b76ec,0x35b42469,0x8768088b},
+{0x834bf11c,0x893041a6,0xfbd260d6,0x2d944658},
+{0xa0aafe39,0xb2e78a0a,0x9787b679,0xabad282d},
+{0x83fa9fd0,0x95534f4b,0xc81cd185,0x55f60b8a},
+{0xea82a5e9,0x677b0bf1,0x4930061d,0x9f678be0},
+{0x735dda06,0xba8cf349,0xf70ade7d,0x1202d45d},
+{0xcb40ce40,0x490c44e6,0xadf1af60,0xccb1f81a},
+{0xd93e9fec,0xe32f636a,0xb93d1fa7,0x3a6b765e},
+{0xdf0c87ca,0x3a529193,0x851b2f76,0x0bc7141c},
+{0x05b2f330,0x9f69b5fa,0xaa428d31,0xac88d110},
+{0x1c0c4dca,0xa35f3c72,0xa956c31b,0x7dbe7fad},
+{0xeed1e431,0x1166648f,0xb492d014,0x25592e6f},
+{0xbaca3593,0x4b0f7ba4,0xf9ad5aee,0xb7aa1606},
+{0x230f76b5,0x1139fcbc,0xaf6da823,0x2a007b46},
+{0xe10cc036,0x80bff8dd,0xc487d20f,0x3ff07911},
+{0x2810fe5d,0x738a616f,0x31fcab25,0x8471cfee},
+{0x637d7bf9,0xe6e44c83,0x72c7b44c,0x13ffd522},
+{0xcd8c080e,0x501a9f44,0x96bcb5cf,0x35c7eb31},
+{0x4d2f89e5,0x53dabfa2,0xb4688261,0xc16eed4e},
+{0x93b9050b,0x5be7fa5d,0x18670a44,0x3d2e8456},
+{0x6366c565,0xe2637cc2,0x81991664,0x5f23f909},
+{0x1bd3abdd,0x006e052a,0x15a0ed8c,0xd8ada32f},
+{0xc994c0f7,0xece89aa1,0x246e02f6,0x4cee3b85},
+{0xc6ef8878,0xa1d76898,0xce6168d7,0xdfa16b1f},
+{0x700da326,0x2619930e,0x4caa5968,0x59e3abe6},
+{0x856a3cad,0xacc2c33d,0x3bc61929,0x2eae13e9},
+{0x07f819d2,0xd5606875,0x4f6b2e6b,0x1eeca72a},
+{0x3d18ea86,0xdbb4bd42,0x78075765,0xd667bfe4},
+{0xbe81f615,0xec5e88aa,0x988871bb,0xa58383db},
+{0xaffa1f4e,0x65a0d22e,0xe9392773,0x4b3b6ea8},
+{0x879b6826,0x0f2d90af,0x9c0faa68,0x23c50814},
+{0x16a8fa7f,0xd28e39db,0xe1bf1689,0x81141b58},
+{0x08f20f2e,0x5e7c0849,0xcf82126c,0x55d3f2dc},
+{0x29df49ad,0x6b7075b9,0x80c5d50e,0x9376d286},
+{0x61d7bfc9,0xc391104a,0x457a6f72,0xa4e39391},
+{0x8de80652,0x5792608d,0xf78d1f46,0x1b30848e},
+{0x6cfd4338,0x1ee527a3,0xc36d8800,0x4c3a3fa6},
+{0xfc20c838,0x5f905fe3,0x3262dad2,0x3f4d786c},
+{0xbac1bbd1,0xa9d88edf,0x2540bf26,0x7f7bb536},
+{0xb340a716,0x04477c62,0x8cbd399b,0x49ae3e82},
+{0xe5122fda,0x06f8a717,0x6a74fb7f,0x16dc278f},
+{0xdd97bb16,0x717bb119,0x1c532e28,0x9c60744c},
+{0x3822693b,0x4162c166,0x07d7cfd2,0xe0fd0dcb},
+{0xe7409a2c,0x63fdfae9,0x746cb10a,0x6bf0ad2b},
+{0xd465cd1a,0x5b05a503,0xd54d2a40,0x6f98eedc},
+{0xcf46323a,0xe866b318,0xed155930,0xe5bde5b2},
+{0xe3b07639,0x0b8d6324,0x760e29b3,0x70b0757e},
+{0x71afca08,0x0d27921c,0x19dfe2f1,0xf760a29c},
+{0x39846278,0x3e267cee,0x8212650a,0x1354830b},
+{0xeff59b41,0xd0b5c3fe,0xc1d4602f,0x1ad0a73f},
+{0xbe877473,0x1719120f,0x74ea6b4b,0x2c1f737f},
+{0x089a47bf,0x55a03027,0x05cd7451,0xec378f17},
+{0x309fea5d,0x5e501bc9,0xa7e66bd3,0x22119872},
+{0x2e2245c7,0xc95928d1,0x3cfe99b7,0x493ae7a1},
+{0x89034178,0x27a730e9,0xfcb8ac5c,0x08fc2f6d},
+{0x163f98de,0x97dba8a7,0x85ca93cb,0xeb5dc3e5},
+{0x063e1a1c,0xbf70e24c,0xfa44aff1,0xea79a794},
+{0x62fd1b79,0xabdbfb2c,0x294391ec,0x4e548903},
+{0x81f82bdf,0xc1e2212f,0xeb323e47,0x8a035ea9},
+{0x938f17f2,0xd7b4f4e3,0xa6524903,0xce90d4c7},
+{0xc2c3d170,0x4e92a96b,0x3dc642d6,0x7428a035},
+{0x42ffc9c6,0xe6956db6,0x3c5b5056,0xbe1dc1dd},
+{0xfdb57f6d,0xb473be55,0x77da9d50,0xfc4deaeb},
+{0xaf9410d4,0x7617347b,0xbc5c959a,0xde3aa1e5},
+{0x7af9bd37,0xf6ee13d9,0x0e878d33,0xad754b13},
+{0x61a1a037,0x5d60be5a,0x5318c92d,0x0d2defde},
+{0xdecd4ee1,0x1b3939a5,0x42c58f49,0xffcb5d9a},
+{0x4f38706e,0xbbff414a,0x1522130f,0x2fe1a225},
+{0x2ec120f9,0x56863c05,0x8dae9599,0x8cbf5dbd},
+{0xcb99e13d,0xbd111b43,0x2bfddfbd,0x9453c9d8},
+{0xb3131a0b,0x1b8ed229,0x698e033c,0x83753dde},
+{0x21f17fb0,0x92346c94,0xb8530322,0x8e804091},
+{0x5896fde5,0xd77f371c,0x355261a1,0x69aba8b4},
+{0x9d805551,0xf7d104c3,0xf3403eac,0xbef10cbd},
+{0xe203631e,0xd52a8eb3,0x99977810,0xa154635c},
+{0xb53d09dc,0x47282d39,0xa6b9bc46,0x5a41cbda},
+{0x8b42f8a6,0x54fb5062,0x98d98f2c,0x4048d568},
+{0x6b2bf36a,0xf410b33e,0x8ea5418d,0x52a57797},
+{0xc9229186,0xe31d6507,0x58b4743e,0x2e1713d2},
+{0xaa2f03cb,0x738073d9,0xf0cf1f6b,0x1107acbb},
+{0x1f9f0ad0,0x6768e414,0xd7491dc2,0x96edd0e2},
+{0xe3573f40,0x0e0e17ec,0xf20a8a3f,0x9b87cc8f},
+{0x0c0b0394,0xba487373,0x7ae81327,0xe8d96e96},
+{0xd030039d,0x3e749d93,0x5d8d4d0e,0xf15318e9},
+{0x868c16e8,0x88a83024,0x122c2ba1,0xf96dd833},
+{0x8721acf3,0x7bd8a9be,0x58bfae5c,0xa5e7fed7},
+{0x92a49adc,0x95f4060a,0x76e7e096,0xf352adec},
+{0x2345cb15,0x4a4fb7c2,0x228b9490,0x20a4cf00},
+{0x7b57e2b2,0x0f6c9c4e,0x45ee2dea,0x99f99fab},
+{0x7a4cf357,0x784f4592,0x91f103bd,0x238a8489},
+{0xa91b67db,0xe1adabff,0x70022b11,0xf982c541},
+{0x09d612af,0x15f64357,0x4de883fb,0x6169f8a8},
+{0x22f42165,0xf107c715,0xad84f19a,0xaaa5b394},
+{0xce988ac8,0x34d6e092,0xc81b1d7a,0xc2c0b4e2},
+{0xdc3ea10c,0x8b9f3b3e,0x45320d28,0x4bcab7fa},
+{0x7b7a73b3,0x6832cba1,0x84c9ccf5,0x1679377f},
+{0x3ea8a972,0x92bec59b,0x4250cb29,0xe1cec2b7},
+{0xa4b2f347,0xe0748dd3,0xd23b83d1,0xe74a5af6},
+{0x547fb502,0xf754ad91,0x24350364,0x15fe666c},
+{0xdd5d6c6b,0x061c403a,0x6c38ce6b,0xebaf2e4a},
+{0x8f923f07,0x1a414df0,0x009b4394,0x62afb2c5},
+{0x9569e4f9,0xed87c1d7,0x6331e5b0,0x18cb1f0b},
+{0x30919430,0x8a60b6cc,0xc862a0fb,0x821625ea},
+{0xda80a2d4,0xa76d27ad,0x8d09c4b1,0x1ad8f187},
+{0x043c2f3e,0x79345a4d,0xbe736946,0x7e91d31c},
+{0x507371f8,0x4413bbe9,0xd9b1b1e6,0x810ebfec},
+{0xb03133fe,0xbb3a2ed0,0xd0e672be,0x2ce8c128},
+{0xb0a7215c,0xc7f9727f,0x4d165329,0x2ca5fe24},
+{0x804cfc2c,0xa4a5ebd7,0xa998a8d8,0xc085faf4},
+{0x22f1e6ee,0xf21b641a,0x2be9b979,0xdadd02e4},
+{0xa4fb4025,0x175dfd91,0x7bb8d0bb,0x99ca1700},
+{0x1f958be3,0x8b4a81dd,0x7b0f3c55,0x6b5900c7},
+{0x2850ddee,0x482430dc,0x19c4e3fc,0x149326d4},
+{0x610f8f14,0xfb509efe,0x72660a7b,0xaf9b5c86},
+{0x41600abd,0xde1bba77,0x8aa48714,0x528d5b5c},
+{0xf77ea87f,0xee4bacbe,0x081b8a19,0xad4e3ac1},
+{0x08612899,0x3a80b5f4,0x52cf8a9b,0x66bbef0e},
+{0xf6a6cbf9,0xe95a98cb,0x48229a41,0xc29b1616},
+{0x38aa4210,0xf661366a,0x23fabb55,0xa98a077d},
+{0x7f62945c,0xc81629a5,0x85f18dd9,0x9ba7a22b},
+{0x3f122bb9,0x3f58df3c,0xaffad9d7,0x54e96057},
+{0x93156fd6,0xd3c8e163,0x695d5798,0xf9bfe0ad},
+{0x1e88d32f,0x3476812d,0xea5b5bbd,0x345ab38c},
+{0x7ed6ac4b,0xe7a02cdb,0xe1fc0196,0xabbd50f1},
+{0xe5c3b1c7,0xd50597dc,0xb373364d,0xcf9d612e},
+{0xb53982da,0xe44ce6dc,0xc1cf016a,0xd5b743e5},
+{0x848d5379,0x594cc3e5,0xec8cde6b,0x8b3b0a90},
+{0xafdf7a90,0xd6dd709e,0xa1e2cd85,0xb36883de},
+{0x5f38fb38,0x9ed4ef55,0xd931a44e,0x968f7c1e},
+{0xbd8340f0,0x45dc35bc,0x7dee4bee,0x6619f26a},
+{0x009443c0,0xbd75deff,0x1f67b14a,0xd72cd8d0},
+{0x4df2a323,0x36cc5cd2,0xfb31ff63,0x2b6cb70e},
+{0x5f00903c,0x7b4f16f8,0x3638f65b,0x08d1f343},
+{0xff140de1,0x975278c6,0x8c8c99c0,0xeee649d1},
+{0x99d07ff0,0x7c118702,0x003fbef3,0x866fc947},
+{0x200e93c9,0x0da381e7,0x192133a9,0xf7a68932},
+{0x1e19e29e,0x39ae8c0f,0xb9d35b74,0x7885c910},
+{0xbab75a0a,0x23e6588a,0x54d41722,0x9ff5a933},
+{0x445e3f24,0xa19c14f0,0x61b86fdf,0x66ba5cde},
+{0x9c87212f,0xc213ca35,0x8e628c29,0x1467b5ad},
+{0x50e2ea04,0xf5423dea,0xf0cda44f,0xe7f292a4},
+{0x03b3223b,0xcb9575f7,0xfceb53ac,0x5f4b8d44},
+{0xbf74eda8,0x787dfaa0,0x10f158b9,0x44dc2d7e},
+{0x1fe91a85,0x5e8f979b,0xed50a89c,0x92b652d1},
+{0x89d4883c,0xde28579b,0x9b6b7d66,0xa00cbc26},
+{0x548ecb0d,0xa8a8c49b,0x17719db6,0x302e7673},
+{0xe8d040ef,0x5431091a,0x883af6cd,0xf60d77c9},
+{0x2e88e4ae,0xeb4ddd4c,0xdf2c8a1c,0x49766a25},
+{0xa7f6df0e,0x6c24a6b1,0x463bbe9e,0x0383f419},
+{0x070da0df,0x1a13457f,0x4d46ccb3,0xdc5da545},
+{0x7dbc10d3,0xf0f6f6fa,0x11b20467,0xf1c57633},
+{0x5275c183,0xd1aa76ea,0x1ee695c3,0xeeb67943},
+{0x2bdbc34e,0x386f49d1,0xe331e3ba,0x4f0f91ac},
+{0x14bed861,0xbd18d697,0x02963076,0xddbc03b4},
+{0x39aec481,0x29748962,0xebb2989f,0xa0b873d2},
+{0x0202df24,0x2b36b9d5,0xe069f74b,0xae89a4c7},
+{0x8fbefc48,0xb68a6c2e,0x9c5fcd06,0x5fdc97bc},
+{0xede610bc,0xd1e0d1dd,0x7f7fec84,0x9fb297e0},
+{0xc6723f15,0xcc01ba4e,0x076c641e,0xee2cc9ef},
+{0x22e2b2cc,0xff9fb668,0xb002f1df,0xfbef9e6f},
+{0x6c8bde6d,0xc1cfdb1a,0xeffdbcdb,0xd74ea82d},
+{0x1f3ffa1d,0x5c07754f,0x44d4b8bc,0x56596d99},
+{0xcbb70edb,0xe55af523,0x1846a284,0x0cbf213c},
+{0xf8341166,0xd2c69100,0x70f4304a,0x0fbd0f25},
+{0x90800913,0x94d5e5ed,0xa62431e6,0xab8ad463},
+{0x164eadbb,0x79e26abc,0x416a7056,0x3d8a3921},
+{0x16061f80,0xa33b2975,0xb218851d,0x0d369d49},
+{0xac24d8c4,0x4fe97c8e,0xd09dd89e,0x56d03033},
+{0xce78ce65,0x1e161951,0x0d7405f9,0xeaef2b3b},
+{0xcab7fe13,0x480487fb,0xb0a886f2,0x27b7b925},
+{0x5e27d951,0x746f1313,0xd755c000,0x64d3d793},
+{0xe1fe9327,0xa3f984c5,0xbf1ce31e,0x7193e590},
+{0x248b08e1,0x779a5f02,0x0b77278f,0x8184ce7f},
+{0x08b866d3,0xee8515d3,0x075d381e,0xf890f9ef},
+{0x89a70dd2,0x19993506,0x3c6c8d22,0x27d74b52},
+{0x481a0e47,0xbf04a70f,0x9d7b25fc,0x10a05e73},
+{0x8f177f27,0x98e90f5c,0xe4725c4e,0xc5e4c4f6},
+{0xf261602b,0x70ec416b,0xdf26c965,0xd2e16c42},
+{0xa7d0f663,0xfe1f418d,0xbfd13549,0xa7eadf55},
+{0xcda4caf5,0xb00ad62a,0xcab58e7f,0x905c5a0b},
+{0x885c3809,0xbc088ea2,0x264398d4,0x2c6f88f3},
+{0x54d01c16,0x631a11cb,0xf8892267,0xfb5390d1},
+{0x36a23cdf,0xdaa2f9ba,0x76f7ad35,0x86a948ac},
+{0xf0405bab,0x048ea965,0x69b4bcef,0x2d41cea7},
+{0x2c3561cc,0x9de5633d,0xb3f9f2b2,0x90f0e610},
+{0x4eebddfe,0x39afd2ce,0xd45aa43d,0x940bf668},
+{0x79838fec,0x73d9fb07,0xc8f222da,0x6ac76ad4},
+{0x38d355f0,0x1f1cc653,0x9851e321,0xc03fdaff},
+{0x85dfe841,0xe2b7aa03,0x080e0a18,0x37a1b0f2},
+{0xa315ecf9,0xa746581d,0x05b3c66c,0xa9b6e4aa},
+{0x7ef4a582,0xea2bd629,0x82e42dbc,0xa15b8a38},
+{0xa3615d4a,0x3ea8f313,0xb6539584,0x6d523306},
+{0x1a7c85d2,0xc429859f,0x9dbdbd86,0x19830572},
+{0xdfd77bda,0x9b4c4876,0x2e18a4b1,0x1a27b66f},
+{0x59ab3712,0x68e173ce,0xc67b2c68,0xef155823},
+{0x2de46d99,0x21c21137,0xdf3c62a9,0x7f4ea769},
+{0xcc4136e6,0x69e15d06,0xfc4cf50f,0x4d3bfe8b},
+{0xbd3f0175,0x83eff59d,0x1c45d456,0xcc9530df},
+{0x8cd582d8,0xa6147f4c,0xd3f749d6,0xd0c19e53},
+{0xde01c733,0xb0796358,0x6294065d,0xc7761457},
+{0xbdae5087,0x76eb5294,0x0306327b,0x35a5283e},
+{0x93426b44,0x7a2278ac,0xb90b5f95,0xc08d5aaf},
+{0x7096d988,0x636eab87,0x94416c92,0x65621336},
+{0xe9468627,0x0891e6cd,0x35188a42,0x6ce8b12a},
+{0xd0a68588,0x7bf1403a,0xbf72d8f7,0xa12d5120},
+{0xa418663a,0x830c6326,0xfe00a86f,0x5932135b},
+{0x1d2ce956,0x95f9f5fd,0x2ef30d0e,0x3890c2c1},
+{0x5e98ce4a,0x69f1bbb0,0xd59d25e5,0x3f9f5c8d},
+{0xfe8fed92,0xa91d4c69,0x4919f42a,0x6774466d},
+{0x0fa149aa,0x852b931d,0x44e82356,0x210b28af},
+{0x083985e8,0x0085a625,0xff7a8bda,0x1984b3b9},
+{0x6d97bde7,0x7bbfd0ae,0xea7b36c5,0x4a0580b2},
+{0xbaae4f30,0xe1aa01c1,0x187eb9be,0x86111457},
+{0x307dd97a,0xd014e4de,0x951c1923,0x783a099c},
+{0xca7150de,0xdc0d51d6,0x4b4c0871,0x9f1088bb},
+{0xa6e2180d,0x930635d1,0x7a6057df,0x03a7c0b1},
+{0x7791c086,0xda5aa454,0x9a6e7ac2,0xed7279d0},
+{0xa2b8fb40,0xcdb48947,0xbd1c99c4,0xe728b4a3},
+{0x18cd2ffb,0xcd8c1ad9,0x51c9b2ed,0xb9c439d6},
+{0x64c6ffd0,0x0347766c,0xdc78263d,0x5be61d3f},
+{0xcff092ea,0xf311410a,0xe9e212d1,0xc08fd9cf},
+{0xdb5a3aee,0x9cef0126,0x0bccea65,0xb9534b67},
+{0x476d8ff6,0x4499938c,0xe7f59508,0x3570ab02},
+{0x77c1c2c6,0xaae01b5f,0xcd3cd74a,0x925fd46f},
+{0x1edf2d06,0x28f28308,0xb1f57d3a,0x73fa0a8a},
+{0xe95b317b,0xe8548938,0x1c0f57a2,0x2467a337},
+{0xf5569647,0xa53b9496,0xf8564c17,0xc99fa57b},
+{0xd09e2e97,0xfd93dbab,0xbe5df18d,0x2f407e27},
+{0x35a8cd56,0x96a4d06d,0xac3affbd,0xe17beffc},
+{0,0,0,0}
+};
+
+#define UDF_NUMBER_OF_KEYS   572
+UCHAR RegKeyName0[] =
+    "\x2b\x03\x01\x0c\x0b\x0d\x01\x03\x0b\x0c"
+    "\x89\x8e\x94\x81\x80\xdc\x88\x93\xde\x8e"
+    "\x8a\xde\xd9\x8a\x83\xcf\x89\x8e\xd4\xcc"
+    "\x88\x98\x8b\xd8\x95\x9b\xe3\xce\xd9\xcb"
+    "\x1f\x11\x02\x15\x09\x5f\x5f\x4d\x5f\x5f"
+    "\xc1\xc1\xb4\x83\x81\x94\xb7\xb6\xb0\x9f"
+    "\x82\xeb\xff\xe8\xd5\xd9\xdf\x8a\x93\x91"
+    "\xc5\xde\x9d\xd4\xcf\xd8\x9d\xf6\xce\xd9"
+    "\x4d\x03\x03\x01\x4c\x03\x01\x05\x02\x1e"
+    "\x94\x83\x81\xdf\x90\x82\x89\x82\x95\x9e"
+    ;
+
diff --git a/reactos/drivers/filesystems/udfs/Include/md5.h b/reactos/drivers/filesystems/udfs/Include/md5.h
new file mode 100644 (file)
index 0000000..9638ae9
--- /dev/null
@@ -0,0 +1,65 @@
+/* MD5.H - header file for MD5C.C
+ * $FreeBSD: src/sys/sys/md5.h,v 1.16 2002/06/24 14:18:39 mux Exp $
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#ifndef _SYS_MD5_H_
+#define _SYS_MD5_H_
+/* MD5 context. */
+typedef struct UDF_MD5Context {
+  uint32 state[4];     /* state (ABCD) */
+  uint32 count[2];     /* number of bits, modulo 2^64 (lsb first) */
+  unsigned char buffer[64];    /* input buffer */
+} UDF_MD5_CTX;
+
+#ifdef __cplusplus
+#define MD5_DECL extern "C"
+#else
+#define MD5_DECL extern
+#endif
+
+MD5_DECL
+void   UDF_MD5Init (UDF_MD5_CTX *);
+
+MD5_DECL
+void   UDF_MD5Update (UDF_MD5_CTX *, const unsigned char *, unsigned int);
+
+MD5_DECL
+void   UDF_MD5Pad (UDF_MD5_CTX *);
+
+MD5_DECL
+void   UDF_MD5Final (unsigned char [16], UDF_MD5_CTX *);
+
+MD5_DECL
+char * UDF_MD5End(UDF_MD5_CTX *, char *);
+
+typedef struct _UDF_MD5_DIGEST {
+    uint8 d[16];
+} UDF_MD5_DIGEST , *PUDF_MD5_DIGEST;
+
+/*char * MD5File(const char *, char *);
+char * MD5FileChunk(const char *, char *, off_t, off_t);
+char * MD5Data(const unsigned char *, unsigned int, char *);*/
+
+#endif /* _SYS_MD5_H_ */
diff --git a/reactos/drivers/filesystems/udfs/Include/md5c.c b/reactos/drivers/filesystems/udfs/Include/md5c.c
new file mode 100644 (file)
index 0000000..93b5d13
--- /dev/null
@@ -0,0 +1,567 @@
+/*
+ * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ *
+ * This code is the same as the code published by RSA Inc.  It has been
+ * edited for clarity and style only.
+ */
+
+/*
+ * This file should be kept in sync with src/lib/libmd/md5c.c
+ */
+//#include "md5.h"
+
+void UDF_MD5Transform(uint32 [4], const unsigned char [64]);
+
+/*
+ * Encodes input (uint32) into output (unsigned char). Assumes len is
+ * a multiple of 4.
+ */
+
+#define htole32(a)  (a)
+#define le32dec(a)  (*(a))
+
+void
+UDF_Encode (unsigned char *output, uint32 *input, unsigned int len)
+{
+    unsigned int i;
+    unsigned int *op = (unsigned int *)output;
+
+    for (i = 0; i < len / 4; i++)
+        op[i] = htole32(input[i]);
+}
+
+/*
+ * Decodes input (unsigned char) into output (uint32). Assumes len is
+ * a multiple of 4.
+ */
+
+void
+UDF_Decode (uint32 *output, const unsigned char *input, unsigned int len)
+{
+    unsigned int i;
+    const unsigned int *ip = (const unsigned int *)input;
+
+    for (i = 0; i < len / 4; i++)
+        output[i] = le32dec(&ip[i]);
+}
+
+static const unsigned char PADDING[64] = {
+  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions. */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits. */
+#ifdef _X86_
+__declspec (naked)
+uint32
+__fastcall
+ROTATE_LEFT(
+    uint32 x, // ECX
+    uint32 n  // EDX
+    )
+{
+  _asm {
+    push  ecx
+    mov   eax,ecx
+    mov   ecx,edx
+    rol   eax,cl
+    pop   ecx
+    ret
+  }
+}
+#else   // NO X86 optimization , use generic C/C++
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+#endif // _X86_
+
+/*
+ * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+ * Rotation is separate from addition to prevent recomputation.
+ */
+
+void
+FF(
+/*    uint32 &a,
+    uint32 b,
+    uint32 c,
+    uint32 d,*/
+    uint32 a[4],
+    uint32 x,
+    uint32 s,
+    uint32 ac
+    )
+{
+    a[0] += F (a[1], a[2], a[3]) + (x) + (uint32)(ac);
+    a[0] = ROTATE_LEFT (a[0], (s));
+    a[0] += (a[1]);
+}
+
+void
+GG(
+/*    uint32 &a,
+    uint32 b,
+    uint32 c,
+    uint32 d,*/
+    uint32 a[4],
+    uint32 x,
+    uint32 s,
+    uint32 ac
+    )
+{
+/*    a += G ((b), (c), (d)) + (x) + (uint32)(ac);
+    a = ROTATE_LEFT ((a), (s));
+    a += (b);*/
+    a[0] += G (a[1], a[2], a[3]) + (x) + (uint32)(ac);
+    a[0] = ROTATE_LEFT (a[0], (s));
+    a[0] += (a[1]);
+}
+
+void
+HH(
+/*    uint32 &a,
+    uint32 b,
+    uint32 c,
+    uint32 d,*/
+    uint32 a[4],
+    uint32 x,
+    uint32 s,
+    uint32 ac
+    )
+{
+/*    a += H ((b), (c), (d)) + (x) + (uint32)(ac);
+    a = ROTATE_LEFT ((a), (s));
+    a += (b);*/
+    a[0] += H (a[1], a[2], a[3]) + (x) + (uint32)(ac);
+    a[0] = ROTATE_LEFT (a[0], (s));
+    a[0] += (a[1]);
+}
+
+void
+II(
+/*    uint32 &a,
+    uint32 b,
+    uint32 c,
+    uint32 d,*/
+    uint32 a[4],
+    uint32 x,
+    uint32 s,
+    uint32 ac
+    )
+{
+/*    a += I ((b), (c), (d)) + (x) + (uint32)(ac);
+    a = ROTATE_LEFT ((a), (s));
+    a += (b);*/
+    a[0] += I (a[1], a[2], a[3]) + (x) + (uint32)(ac);
+    a[0] = ROTATE_LEFT (a[0], (s));
+    a[0] += (a[1]);
+}
+
+#if 0   // NO X86 optimization , use generic C/C++
+
+#define FF(a, b, c, d, x, s, ac) { \
+    (a) += F ((b), (c), (d)) + (x) + (uint32)(ac); \
+    (a) = ROTATE_LEFT ((a), (s)); \
+    (a) += (b); \
+    }
+#define GG(a, b, c, d, x, s, ac) { \
+    (a) += G ((b), (c), (d)) + (x) + (uint32)(ac); \
+    (a) = ROTATE_LEFT ((a), (s)); \
+    (a) += (b); \
+    }
+#define HH(a, b, c, d, x, s, ac) { \
+    (a) += H ((b), (c), (d)) + (x) + (uint32)(ac); \
+    (a) = ROTATE_LEFT ((a), (s)); \
+    (a) += (b); \
+    }
+#define II(a, b, c, d, x, s, ac) { \
+    (a) += I ((b), (c), (d)) + (x) + (uint32)(ac); \
+    (a) = ROTATE_LEFT ((a), (s)); \
+    (a) += (b); \
+    }
+#endif // _X86_
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context. */
+
+static const uint32 UDF_MD5Init_state[4] = {
+    0x67452301,
+    0xefcdab89,
+    0x98badcfe,
+    0x10325476
+    };
+    
+void
+UDF_MD5Init (
+    UDF_MD5_CTX *context
+    )
+{
+
+    context->count[0] = context->count[1] = 0;
+
+    /* Load magic initialization constants.  */
+#if 0
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xefcdab89;
+    context->state[2] = 0x98badcfe;
+    context->state[3] = 0x10325476;
+#endif
+    memcpy(context->state, UDF_MD5Init_state, sizeof(UDF_MD5Init_state));
+}
+
+/* 
+ * MD5 block update operation. Continues an MD5 message-digest
+ * operation, processing another message block, and updating the
+ * context.
+ */
+
+void
+UDF_MD5Update (
+    UDF_MD5_CTX *context,
+    const unsigned char *input,
+    unsigned int inputLen
+    )
+{
+    unsigned int i, index, partLen;
+
+    /* Compute number of bytes mod 64 */
+    index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+    /* Update number of bits */
+    if ((context->count[0] += ((uint32)inputLen << 3))
+        < ((uint32)inputLen << 3))
+        context->count[1]++;
+    context->count[1] += ((uint32)inputLen >> 29);
+
+    partLen = 64 - index;
+
+    /* Transform as many times as possible. */
+    if (inputLen >= partLen) {
+        memcpy((void *)&context->buffer[index], (const void *)input,
+            partLen);
+        UDF_MD5Transform (context->state, context->buffer);
+
+        for (i = partLen; i + 63 < inputLen; i += 64)
+            UDF_MD5Transform (context->state, &input[i]);
+
+        index = 0;
+    }
+    else
+        i = 0;
+
+    /* Buffer remaining input */
+    memcpy ((void *)&context->buffer[index], (const void *)&input[i],
+        inputLen-i);
+}
+
+/*
+ * MD5 padding. Adds padding followed by original length.
+ */
+
+void
+UDF_MD5Pad (
+    UDF_MD5_CTX *context
+       )    
+{
+    unsigned char bits[8];
+    unsigned int index, padLen;
+
+    /* Save number of bits */
+    UDF_Encode (bits, context->count, 8);
+
+    /* Pad out to 56 mod 64. */
+    index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+    padLen = (index < 56) ? (56 - index) : (120 - index);
+    UDF_MD5Update (context, PADDING, padLen);
+
+    /* Append length (before padding) */
+    UDF_MD5Update (context, bits, 8);
+}
+
+/*
+ * MD5 finalization. Ends an MD5 message-digest operation, writing the
+ * the message digest and zeroizing the context.
+ */
+
+void
+UDF_MD5Final (
+    unsigned char digest[16],
+    UDF_MD5_CTX *context
+    )
+{
+    /* Do padding. */
+    UDF_MD5Pad (context);
+
+    /* Store state in digest */
+    UDF_Encode (digest, context->state, 16);
+
+    /* Zeroize sensitive information. */
+    memset ((void *)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block. */
+
+static const uint32 UDF_MD5Transform_dwords[4][16] = {
+    {
+    0xd76aa478,    0xe8c7b756,    0x242070db,    0xc1bdceee,
+    0xf57c0faf,    0x4787c62a,    0xa8304613,    0xfd469501,
+    0x698098d8,    0x8b44f7af,    0xffff5bb1,    0x895cd7be,
+    0x6b901122,    0xfd987193,    0xa679438e,    0x49b40821
+    },
+    {
+    0xf61e2562,    0xc040b340,    0x265e5a51,    0xe9b6c7aa,
+    0xd62f105d,     0x2441453,    0xd8a1e681,    0xe7d3fbc8,
+    0x21e1cde6,    0xc33707d6,    0xf4d50d87,    0x455a14ed,
+    0xa9e3e905,    0xfcefa3f8,    0x676f02d9,    0x8d2a4c8a
+    },
+    {
+    0xfffa3942,    0x8771f681,    0x6d9d6122,    0xfde5380c,
+    0xa4beea44,    0x4bdecfa9,    0xf6bb4b60,    0xbebfbc70,
+    0x289b7ec6,    0xeaa127fa,    0xd4ef3085,     0x4881d05,
+    0xd9d4d039,    0xe6db99e5,    0x1fa27cf8,    0xc4ac5665
+    },
+    {
+    0xf4292244,    0x432aff97,    0xab9423a7,    0xfc93a039,
+    0x655b59c3,    0x8f0ccc92,    0xffeff47d,    0x85845dd1,
+    0x6fa87e4f,    0xfe2ce6e0,    0xa3014314,    0x4e0811a1,
+    0xf7537e82,    0xbd3af235,    0x2ad7d2bb,    0xeb86d391
+    }
+};
+
+static const uint32 UDF_MD5Transform_idx[4][16] = {
+    {
+     0,  1,  2,  3,  4,  5,  6,  7,
+     8,  9, 10, 11, 12, 13, 14, 15
+    },
+    {
+     1,  6, 11,  0,  5, 10, 15,  4,
+     9, 14,  3,  8, 13,  2,  7, 12
+    },
+    {
+     5,  8, 11, 14,  1,  4,  7, 10,
+    13,  0,  3,  6,  9, 12, 15,  2
+    },
+    {
+     0,  7, 14,  5, 12,  3, 10,  1,
+     8, 15,  6, 13,  4, 11,  2,  9
+    }
+};
+
+static const uint32 UDF_MD5Transform_Sxx[4][4] = {
+    {    7 ,    12,    17,    22    },
+    {    5 ,    9 ,    14,    20    },
+    {    4 ,    11,    16,    23    },
+    {    6 ,    10,    15,    21    }
+};
+
+void
+UDF_MD5Rotate (
+    uint32 state[4]
+    )
+{
+    uint32 a = state[3];
+    /* Load magic initialization constants.  */
+#if 0
+    state[3] = state[0];
+    state[2] = state[3];
+    state[1] = state[4];
+#endif
+    memmove(&state[1], &state[0], sizeof(state[0])*3);
+    state[0] = a;
+}
+
+typedef void (*P_MD5_XX)
+    (
+/*    uint32 &a,
+    uint32 b,
+    uint32 c,
+    uint32 d,*/
+    uint32 a[4],
+    uint32 x,
+    uint32 s,
+    uint32 ac
+    );
+
+void
+UDF_MD5Transform (
+    uint32 state[4],
+    const unsigned char block[64]
+    )
+{
+//    uint32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+    uint32 x[16];
+    uint32 state1[4];
+    uint32 i, j, k;
+
+    P_MD5_XX MD5_func[] = {FF, GG, HH, II};
+
+    memcpy(state1, state, sizeof(state1));
+
+    UDF_Decode (x, block, 64);
+
+    for(j=0; j<4; j++) {
+        for(i=0; i<16;) {
+            for(k=0; k<4; k++, i++) {
+                MD5_func[j] (state1, x[UDF_MD5Transform_idx[j][i]], UDF_MD5Transform_Sxx[j][k], UDF_MD5Transform_dwords[j][i]); /* 1 */
+                UDF_MD5Rotate(state1);
+            }
+        }
+    }
+#if 0
+    for(i=0; i<16;) {
+        #define j 0
+        for(k=0; k<4; k++, i++) {
+            FF (state1, x[UDF_MD5Transform_idx[j][i]], UDF_MD5Transform_Sxx[j][k], UDF_MD5Transform_dwords[j][i]); /* 1 */
+            UDF_MD5Rotate(state1);
+        }
+        #undef j
+    }
+    for(i=0; i<16;) {
+        #define j 1
+        for(k=0; k<4; k++, i++) {
+            GG (state1, x[UDF_MD5Transform_idx[j][i]], UDF_MD5Transform_Sxx[j][k], UDF_MD5Transform_dwords[j][i]); /* 1 */
+            UDF_MD5Rotate(state1);
+        }
+        #undef j
+    }
+    for(i=0; i<16;) {
+        #define j 2
+        for(k=0; k<4; k++, i++) {
+            HH (state1, x[UDF_MD5Transform_idx[j][i]], UDF_MD5Transform_Sxx[j][k], UDF_MD5Transform_dwords[j][i]); /* 1 */
+            UDF_MD5Rotate(state1);
+        }
+        #undef j
+    }
+    for(i=0; i<16;) {
+        #define j 3
+        for(k=0; k<4; k++, i++) {
+            II (state1, x[UDF_MD5Transform_idx[j][i]], UDF_MD5Transform_Sxx[j][k], UDF_MD5Transform_dwords[j][i]); /* 1 */
+            UDF_MD5Rotate(state1);
+        }
+        #undef j
+    }
+#endif //0
+
+#if 0
+    /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+    FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+    FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+    FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+    FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+    FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+    FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+    FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+    FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+    FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+    FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+    FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+    FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+    FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+    FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+    FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+    FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+    /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+    GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+    GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+    GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+    GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+    GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+    GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
+    GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+    GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+    GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+    GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+    GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+    GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+    GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+    GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+    GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+    GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+    /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+    HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+    HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+    HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+    HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+    HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+    HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+    HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+    HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+    HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+    HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+    HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+    HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
+    HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+    HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+    HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+    HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+    /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+    II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+    II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+    II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+    II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+    II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+    II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+    II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+    II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+    II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+    II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+    II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+    II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+    II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+    II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+    II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+    II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+#endif //0
+
+    state[0] += state1[0];
+    state[1] += state1[1];
+    state[2] += state1[2];
+    state[3] += state1[3];
+
+    /* Zeroize sensitive information. */
+    memset ((void *)x, 0, sizeof (x));
+}
diff --git a/reactos/drivers/filesystems/udfs/Include/mem_tools.cpp b/reactos/drivers/filesystems/udfs/Include/mem_tools.cpp
new file mode 100644 (file)
index 0000000..f884232
--- /dev/null
@@ -0,0 +1,952 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifdef MY_USE_INTERNAL_MEMMANAGER
+
+#ifdef _X86_
+
+__inline VOID DbgTouch(IN PVOID addr)
+{
+    __asm {
+        mov  eax,addr
+        mov  al,[byte ptr eax]
+    }
+}
+
+#else   // NO X86 optimization , use generic C/C++
+
+__inline VOID DbgTouch(IN PVOID addr)
+{
+    UCHAR a = ((PUCHAR)addr)[0];
+}
+
+#endif // _X86_
+
+//MEM_ALLOC_DESC Allocs[MY_HEAP_MAX_BLOCKS];
+
+MEM_FRAME_ALLOC_DESC FrameList[MY_HEAP_MAX_FRAMES];
+#ifdef MEM_LOCK_BY_SPINLOCK
+KSPIN_LOCK FrameLock;
+KIRQL oldIrql;
+#define LockMemoryManager()        KeAcquireSpinLock(&FrameLock, &oldIrql)
+#define UnlockMemoryManager()      KeReleaseSpinLock(&FrameLock, oldIrql)
+__inline 
+NTSTATUS
+InitLockMemoryManager() {
+    KeInitializeSpinLock(&FrameLock);
+    return STATUS_SUCCESS;
+}
+#define DeinitLockMemoryManager()  {NOTHING;}
+#else //MEM_LOCK_BY_SPINLOCK
+ERESOURCE FrameLock;
+#define LockMemoryManager()        ExAcquireResourceExclusiveLite(&FrameLock, TRUE)
+#define UnlockMemoryManager()      ExReleaseResourceForThreadLite(&FrameLock, ExGetCurrentResourceThread())
+#define InitLockMemoryManager()    ExInitializeResourceLite(&FrameLock)
+#define DeinitLockMemoryManager()  ExDeleteResourceLite(&FrameLock)
+#endif //MEM_LOCK_BY_SPINLOCK
+ULONG FrameCount;
+ULONG LastFrame;
+BOOLEAN MyMemInitialized = FALSE;
+
+#define MyAllocIsFrameFree(FrameList, i) \
+    (!(FrameList[i].LastUsed || FrameList[i].FirstFree))
+
+#ifdef UDF_DBG
+ULONG MemTotalAllocated;
+PCHAR BreakAddr;
+
+VOID
+MyAllocDumpDescr(
+    PMEM_ALLOC_DESC Allocs,
+    ULONG i
+    )
+{
+    BOOLEAN Used;
+
+    Used = (Allocs[i].Len & MY_HEAP_FLAG_USED) ? TRUE : FALSE;
+    KdPrint(("block %x \t%s addr %x len %x  \t", i, Used ? "used" : "free", Allocs[i].Addr, (Allocs[i].Len) & MY_HEAP_FLAG_LEN_MASK));
+#ifdef MY_HEAP_TRACK_OWNERS
+    KdPrint(("src %x   \t line %d     \t", Allocs[i].Src, Allocs[i].Line));
+#endif
+#ifdef MY_HEAP_TRACK_REF
+    KdPrint(("%s%s", Used ? " " : "-", Allocs[i].Tag ? Allocs[i].Tag : ""));
+#endif
+    KdPrint(("\n"));
+}
+
+//#define CHECK_ALLOC_FRAMES
+
+#define DUMP_MEM_FRAMES
+
+#ifdef DUMP_MEM_FRAMES
+ULONG MyDumpMem = FALSE;
+#endif //DUMP_MEM_FRAMES
+
+#define DUMP_MEM_FRAMES2
+
+//#ifdef CHECK_ALLOC_FRAMES
+VOID
+MyAllocDumpFrame(
+    ULONG Frame
+    )
+{
+    ULONG i;
+    PMEM_ALLOC_DESC Allocs;
+    Allocs = FrameList[Frame].Frame;
+    ULONG k=0;
+    BOOLEAN Used;
+#ifdef DUMP_MEM_FRAMES
+    if(!MyDumpMem)
+#endif //DUMP_MEM_FRAMES
+        return;
+
+    KdPrint(("Dumping frame %x\n",Frame));
+    KdPrint(("FirstFree %x   LastUsed %x  ", FrameList[Frame].FirstFree, FrameList[Frame].LastUsed));
+    KdPrint(("Type %x\n", FrameList[Frame].Type));
+    if(Allocs) {
+        for(i=0;i< (MY_HEAP_MAX_BLOCKS/*-1*/);i++) {
+            Used = (Allocs[i].Len & MY_HEAP_FLAG_USED) ? TRUE : FALSE;
+            KdPrint(("block %x \t%s addr %x len %x  \t", i, Used ? "used" : "free", Allocs[i].Addr, (Allocs[i].Len) & MY_HEAP_FLAG_LEN_MASK));
+#ifdef MY_HEAP_TRACK_OWNERS
+            KdPrint(("src %x   \t line %d     \t", Allocs[i].Src, Allocs[i].Line));
+#endif
+#ifdef MY_HEAP_TRACK_REF
+            KdPrint(("%s%s", Used ? " " : "-", Allocs[i].Tag ? Allocs[i].Tag : ""));
+#endif
+            KdPrint(("\n"));
+            if(!(Allocs[i].Len) && !(Allocs[i].Addr)) {
+                break;
+            }
+            if(Allocs[i].Len & MY_HEAP_FLAG_USED)
+                k += ((Allocs[i].Len) & MY_HEAP_FLAG_LEN_MASK);
+        }
+    }
+    KdPrint(("    Wasted %x bytes from %x\n", MY_HEAP_FRAME_SIZE - k, MY_HEAP_FRAME_SIZE));
+} // end MyAllocDumpFrame()
+
+VOID
+MyAllocDumpFrames(
+    VOID
+    )
+{
+    ULONG i;
+
+    for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
+        if(FrameList[i].Frame) {
+            MyAllocDumpFrame(i);
+        }
+    }
+
+    KdPrint(("\n"));
+
+    for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
+        if(FrameList[i].Frame) {
+            KdPrint(("Addr %x   ", FrameList[i].Frame));
+            KdPrint(("Type %x\n" , FrameList[i].Type));
+        }
+    }
+
+} // end MyAllocDumpFrame()
+
+VOID
+MyAllocCheck(
+    ULONG Frame
+    )
+{
+    ULONG i, j;
+    PMEM_ALLOC_DESC Allocs;
+    Allocs = FrameList[Frame].Frame;
+    ULONG len, addr;
+
+    for(i=0;i< (MY_HEAP_MAX_BLOCKS-1);i++) {
+        len = (Allocs[i].Len & MY_HEAP_FLAG_LEN_MASK);
+        addr = Allocs[i].Addr;
+        if( len != (Allocs[i+1].Addr - addr) ) {
+            if(Allocs[i+1].Addr) {
+                KdPrint(("ERROR! Memory block aliasing\n"));
+                KdPrint(("block %x, frame %x\n", i, Frame));
+                KdPrint(("block descriptor %x\n", &(Allocs[i]) ));
+                BrutePoint();
+                MyAllocDumpFrame(Frame);
+            }
+        }
+#ifdef MY_HEAP_CHECK_BOUNDS
+        if(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) != 0xBAADF00D) {
+            MyAllocDumpDescr(Allocs, i);
+        }
+#endif //MY_HEAP_CHECK_BOUNDS
+    }
+} // end MyAllocCheck()
+
+//#endif //CHECK_ALLOC_FRAMES
+#else
+
+#define MyAllocDumpFrame(a) {}
+#define MyAllocCheck(a) {}
+#define MyAllocDumpFrames() {}
+
+#endif // UDF_DBG
+
+PCHAR
+#ifndef MY_HEAP_TRACK_OWNERS
+__fastcall
+#endif
+MyAllocatePoolInFrame(
+    ULONG Frame,
+    ULONG size
+#ifdef MY_HEAP_TRACK_OWNERS
+   ,USHORT Src,
+    USHORT Line
+#endif
+#ifdef MY_HEAP_TRACK_REF
+   ,PCHAR Tag
+#endif //MY_HEAP_TRACK_REF
+    )
+{
+    ULONG addr;
+    ULONG i;
+    ULONG min_len;
+    ULONG best_i;
+    PMEM_ALLOC_DESC Allocs;
+    PMEM_ALLOC_DESC Allocs0;
+    ULONG LastUsed, FirstFree;
+    ULONG l;
+
+#ifdef CHECK_ALLOC_FRAMES
+    MyAllocCheck(Frame);
+#endif
+
+    if(!size) return NULL;
+#ifdef MY_HEAP_CHECK_BOUNDS
+    size+=MY_HEAP_CHECK_BOUNDS_BSZ;
+#endif
+
+/*    if(size == 0x70) {
+        BrutePoint();
+    }*/
+    // lock frame
+    Allocs0 = FrameList[Frame].Frame;
+    if(!Allocs0) return NULL;
+    best_i = MY_HEAP_MAX_BLOCKS;
+    min_len = 0;
+    LastUsed = FrameList[Frame].LastUsed;
+    FirstFree = FrameList[Frame].FirstFree;
+
+    if(LastUsed >= (MY_HEAP_MAX_BLOCKS-1))
+        return NULL;
+
+    for(i=FirstFree, Allocs = &(Allocs0[i]);i<=LastUsed;i++, Allocs++) {
+        if( !((l = Allocs->Len) & MY_HEAP_FLAG_USED) &&
+             ((l &= MY_HEAP_FLAG_LEN_MASK) >= size) ) {
+            // check if minimal
+            // check for first occurence
+            if(l < min_len || !min_len) {
+                min_len = l;
+                best_i = i;
+            }
+            if(l == size)
+                break;
+        }
+    }
+    // not enough resources
+    if(best_i >= MY_HEAP_MAX_BLOCKS) return NULL;
+    // mark as used
+    Allocs = Allocs0+best_i;
+    addr = Allocs->Addr;
+    // create entry for unallocated tail
+    if(Allocs->Len != size) {     // this element is always FREE
+        if(Allocs[1].Len) {
+            if(Allocs0[MY_HEAP_MAX_BLOCKS-1].Len) return NULL;
+/*            for(i=MY_HEAP_MAX_BLOCKS-1;i>best_i;i--) {
+                Allocs[i] = Allocs[i-1];
+            }*/
+            RtlMoveMemory(&(Allocs[1]), &(Allocs[0]), (LastUsed-best_i+1)*sizeof(MEM_ALLOC_DESC));
+        }
+        Allocs[1].Addr = Allocs->Addr + size;
+        if(Allocs[1].Len) {
+            Allocs[1].Len -= size;
+        } else {
+            Allocs[1].Len = MY_HEAP_FRAME_SIZE - (addr - Allocs0[0].Addr) - size;
+        }
+//        Allocs[best_i+1].Used = FALSE;   // this had been done by prev. ops.
+        FrameList[Frame].LastUsed++;
+    }
+    // update FirstFree pointer
+    if(FirstFree == best_i) {
+        for(i=best_i+1, Allocs++; (i<=LastUsed) && (Allocs->Len & MY_HEAP_FLAG_USED);i++, Allocs++) {
+            // do nothing but scan
+        }
+        FrameList[Frame].FirstFree = i;
+        Allocs = Allocs0+best_i;
+    }
+    Allocs->Len = size | MY_HEAP_FLAG_USED;
+#ifdef MY_HEAP_TRACK_OWNERS
+    Allocs->Src = Src;
+    Allocs->Line = Line;
+#endif
+#ifdef MY_HEAP_TRACK_REF
+    Allocs->Tag = Tag;
+#endif //MY_HEAP_TRACK_REF
+
+//    KdPrint(( "Mem: Allocated %x at addr %x\n", size, (ULONG)addr ));
+    // this will set IntegrityTag to zero
+    *((PULONG)addr) = 0x00000000;
+#ifdef MY_HEAP_CHECK_BOUNDS
+    for(i=0; i<MY_HEAP_CHECK_BOUNDS_SZ; i++) {
+        *((PULONG)(addr+size+(i*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) = 0xBAADF00D;
+    }
+#endif //MY_HEAP_CHECK_BOUNDS
+
+#ifdef UDF_DBG
+    MemTotalAllocated += size;
+#endif
+    return (PCHAR)addr;
+} // end MyAllocatePoolInFrame()
+
+LONG
+__fastcall
+MyFindMemDescByAddr(
+    ULONG Frame,
+    PCHAR addr
+    )
+{
+    ULONG i;
+    ULONG left;
+    ULONG right;
+    PMEM_ALLOC_DESC Allocs;
+
+    Allocs = FrameList[Frame].Frame;
+//    i = FrameList[Frame].LastUsed >> 1;
+//    KdPrint(("Mem: Freeing %x\n", (ULONG)addr)); DEADDA7A
+//    for(i=0;i<MY_HEAP_MAX_BLOCKS;i++) {
+    left = 0;
+    right = FrameList[Frame].LastUsed;
+    if(!right && FrameList[Frame].FirstFree)
+        right = 1;
+    while(left != right) {
+        i = (right + left) >> 1;
+        if( (Allocs[i].Len & MY_HEAP_FLAG_USED) && (Allocs[i].Addr == (ULONG)addr) ) {
+FIF_Found:
+            return i;
+        }
+        if(right - left == 1) {
+            if( (Allocs[i+1].Len & MY_HEAP_FLAG_USED) && (Allocs[i+1].Addr == (ULONG)addr) ) {
+                i++;
+                goto FIF_Found;
+            }
+            break;
+        }
+        if(Allocs[i].Addr && (Allocs[i].Addr < (ULONG)addr)) {
+            left = i;
+        } else {
+            right = i;
+        }
+    }
+    return -1;
+} // end MyFindMemDescByAddr()
+
+VOID
+__fastcall
+MyFreePoolInFrame(
+    ULONG Frame,
+    PCHAR addr
+    )
+{
+    LONG i, j;
+    ULONG pc;
+    ULONG len, len2;
+    PMEM_ALLOC_DESC Allocs;
+
+    Allocs = FrameList[Frame].Frame;
+    pc = 0;
+    i = MyFindMemDescByAddr(Frame, addr);
+    if(i < 0) {
+        KdPrint(("Mem: <<<*** WARNING ***>>> Double deallocation at %x !!!   ;( \n", addr));
+        MyAllocDumpFrame(Frame);
+        BrutePoint();
+        return;
+    }
+    Allocs[i].Len &= ~MY_HEAP_FLAG_USED;
+    len = Allocs[i].Len;  // USED bit is already cleared
+
+#ifdef MY_HEAP_CHECK_BOUNDS
+    for(j=0; j<MY_HEAP_CHECK_BOUNDS_SZ; j++) {
+        ASSERT(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) == 0xBAADF00D);
+        if(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) != 0xBAADF00D) {
+            MyAllocDumpDescr(Allocs, i);
+        }
+    }
+#endif //MY_HEAP_CHECK_BOUNDS
+
+#ifdef UDF_DBG
+    // this is a marker of deallocated blocks
+    // some structures have DWORD IntegrityTag as a first member
+    // so, if IntegrityTag is equal to 0xDEADDA7A we shall return
+    // a <<<*** BIG ERROR MESSAGE ***>>> when somebody try to use it
+    *((PULONG)addr) = 0xDEADDA7A;
+    MemTotalAllocated -= len;
+#endif
+    if((i<MY_HEAP_MAX_BLOCKS-1) && !((len2 = Allocs[i+1].Len) & MY_HEAP_FLAG_USED)) {
+        // pack up
+        if((len2 &= MY_HEAP_FLAG_LEN_MASK)) {
+            len += len2;
+        } else {
+            len = MY_HEAP_FRAME_SIZE - (Allocs[i].Addr - Allocs[0].Addr);
+        }
+        pc++;
+    }
+    if((i>0) && !((len2 = Allocs[i-1].Len) & MY_HEAP_FLAG_USED)) {
+        // pack down
+        len += (len2 & MY_HEAP_FLAG_LEN_MASK);
+        pc++;
+        i--;
+    }
+    if(pc) {
+        // pack
+
+        Allocs[i+pc].Addr = Allocs[i].Addr;
+        Allocs[i+pc].Len = len;
+/*                for(;i<MY_HEAP_MAX_BLOCKS-pc;i++) {
+            Allocs[i] = Allocs[i+pc];
+        }*/
+        RtlMoveMemory(&(Allocs[i]), &(Allocs[i+pc]), (MY_HEAP_MAX_BLOCKS-pc-i)*sizeof(MEM_ALLOC_DESC) );
+/*                for(i=MY_HEAP_MAX_BLOCKS-pc;i<MY_HEAP_MAX_BLOCKS;i++) {
+            Allocs[i].Addr =
+            Allocs[i].Len =
+            Allocs[i].Used = 0;
+        }*/
+        RtlZeroMemory(&(Allocs[MY_HEAP_MAX_BLOCKS-pc]), pc*sizeof(MEM_ALLOC_DESC));
+    }
+    if(FrameList[Frame].FirstFree > (ULONG)i)
+        FrameList[Frame].FirstFree = (ULONG)i;
+    //ASSERT(FrameList[Frame].LastUsed >= pc);
+    if(FrameList[Frame].LastUsed < pc) {
+        FrameList[Frame].LastUsed = 0;
+    } else {
+        FrameList[Frame].LastUsed -= pc;
+    }
+    return;
+} // end MyFreePoolInFrame()
+
+BOOLEAN
+__fastcall
+MyResizePoolInFrame(
+    ULONG Frame,
+    PCHAR addr,
+    ULONG new_len
+#ifdef MY_HEAP_TRACK_REF
+   ,PCHAR* Tag
+#endif //MY_HEAP_TRACK_REF
+    )
+{
+    LONG i, j;
+    ULONG len, len2;
+    PMEM_ALLOC_DESC Allocs;
+
+    if(FrameList[Frame].LastUsed >= (MY_HEAP_MAX_BLOCKS-1))
+        return FALSE;
+    Allocs = FrameList[Frame].Frame;
+    i = MyFindMemDescByAddr(Frame, addr);
+    if(i < 0) {
+        KdPrint(("Mem: <<<*** WARNING ***>>> Double deallocation at %x !!!   ;( \n", addr));
+        MyAllocDumpFrame(Frame);
+        BrutePoint();
+        return FALSE;
+    }
+    if(i>=(MY_HEAP_MAX_BLOCKS-2))
+        return FALSE;
+
+#ifdef MY_HEAP_TRACK_REF
+    *Tag = Allocs[i].Tag;
+#endif //MY_HEAP_TRACK_REF
+
+    len = (Allocs[i].Len & MY_HEAP_FLAG_LEN_MASK);
+
+#ifdef MY_HEAP_CHECK_BOUNDS
+    new_len += MY_HEAP_CHECK_BOUNDS_BSZ;
+    for(j=0; j<MY_HEAP_CHECK_BOUNDS_SZ; j++) {
+        ASSERT(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) == 0xBAADF00D);
+        if(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) != 0xBAADF00D) {
+            MyAllocDumpDescr(Allocs, i);
+        }
+    }
+#endif //MY_HEAP_CHECK_BOUNDS
+    
+    if(new_len > len ) {
+        if(Allocs[i+1].Len & MY_HEAP_FLAG_USED)
+            return FALSE;
+        if(len + (Allocs[i+1].Len & MY_HEAP_FLAG_LEN_MASK) < new_len)
+            return FALSE;
+        Allocs[i].Len += (len2 = (new_len - len));
+        Allocs[i+1].Len -= len2;
+        Allocs[i+1].Addr += len2;
+
+#ifdef MY_HEAP_CHECK_BOUNDS
+        for(j=0; j<MY_HEAP_CHECK_BOUNDS_SZ; j++) {
+            *((PULONG)(addr+new_len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) = 0xBAADF00D;
+        }
+#endif //MY_HEAP_CHECK_BOUNDS
+        
+        if(!Allocs[i+1].Len) {
+            i++;
+            RtlMoveMemory(&(Allocs[i]), &(Allocs[i+1]), (MY_HEAP_MAX_BLOCKS-1-i)*sizeof(MEM_ALLOC_DESC) );
+            RtlZeroMemory(&(Allocs[MY_HEAP_MAX_BLOCKS-1]), sizeof(MEM_ALLOC_DESC));
+            if((ULONG)i<FrameList[Frame].LastUsed)
+                FrameList[Frame].LastUsed--;
+            if(FrameList[Frame].FirstFree == (ULONG)i) {
+                for(;i<MY_HEAP_MAX_BLOCKS;i++) {
+                    if(!(Allocs[i].Len & MY_HEAP_FLAG_USED))
+                        break;
+                }
+                FrameList[Frame].FirstFree = i;
+            }
+        }
+#ifdef UDF_DBG
+        MemTotalAllocated += len;
+#endif
+    } else {
+
+        len2 = len - new_len;
+        if(!len2) return TRUE;
+
+#ifdef MY_HEAP_CHECK_BOUNDS
+        for(j=0; j<MY_HEAP_CHECK_BOUNDS_SZ; j++) {
+            *((PULONG)(addr+new_len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) = 0xBAADF00D;
+        }
+#endif //MY_HEAP_CHECK_BOUNDS
+
+        Allocs[i].Len -= len2;
+        if(Allocs[i+1].Len & MY_HEAP_FLAG_USED) {
+            i++;
+            RtlMoveMemory(&(Allocs[i+1]), &(Allocs[i]), (MY_HEAP_MAX_BLOCKS-i-1)*sizeof(MEM_ALLOC_DESC) );
+
+            Allocs[i].Len = len2;
+            Allocs[i].Addr = Allocs[i-1].Addr + new_len;
+
+            if(FrameList[Frame].FirstFree > (ULONG)i)
+                FrameList[Frame].FirstFree = i;
+            FrameList[Frame].LastUsed++;
+
+        } else {
+            Allocs[i+1].Len += len2;
+            Allocs[i+1].Addr -= len2;
+        }
+#ifdef UDF_DBG
+        MemTotalAllocated -= len2;
+#endif
+    }
+
+    return TRUE;
+} // end MyResizePoolInFrame()
+
+VOID
+__fastcall
+MyAllocInitFrame(
+    ULONG Type,
+    ULONG Frame
+    )
+{
+    PMEM_ALLOC_DESC Allocs;
+
+    Allocs = (PMEM_ALLOC_DESC)DbgAllocatePool(NonPagedPool, sizeof(MEM_ALLOC_DESC)*(MY_HEAP_MAX_BLOCKS+1));
+    if(!Allocs) {
+        KdPrint(("Insufficient resources to allocate frame descriptor\n"));
+        FrameList[Frame].Frame = NULL;
+        MyAllocDumpFrames();
+        BrutePoint();
+        return;
+    }
+    RtlZeroMemory(Allocs, sizeof(MEM_ALLOC_DESC)*(MY_HEAP_MAX_BLOCKS+1));
+    // alloc heap
+    Allocs[0].Addr = (ULONG)DbgAllocatePool((POOL_TYPE)Type, MY_HEAP_FRAME_SIZE);
+    if(!Allocs[0].Addr) {
+        KdPrint(("Insufficient resources to allocate frame\n"));
+        DbgFreePool(Allocs);
+        FrameList[Frame].Frame = NULL;
+        MyAllocDumpFrames();
+        BrutePoint();
+        return;
+    }
+    Allocs[0].Len = MY_HEAP_FRAME_SIZE;
+//    Allocs[0].Used = FALSE;
+    FrameList[Frame].Frame = Allocs;
+    FrameList[Frame].LastUsed =
+    FrameList[Frame].FirstFree = 0;
+    FrameList[Frame].Type = Type;
+    FrameCount++;
+    if(LastFrame < Frame)
+        LastFrame = Frame;
+} // end MyAllocInitFrame()
+
+VOID
+__fastcall
+MyAllocFreeFrame(
+    ULONG Frame
+    )
+{
+    // check if already deinitialized
+    if(!FrameList[Frame].Frame) {
+        BrutePoint();
+        return;
+    }
+    DbgFreePool((PVOID)(FrameList[Frame].Frame)[0].Addr);
+    DbgFreePool((PVOID)(FrameList[Frame].Frame));
+    FrameList[Frame].Frame = NULL;
+    FrameCount--;
+    if(LastFrame == Frame) {
+        LONG i;
+        for(i=LastFrame; i>0; i--) {
+            if(FrameList[i].Frame)
+                break;
+        }
+        LastFrame = i;
+    }
+} // end MyAllocFreeFrame()
+
+PCHAR
+#ifndef MY_HEAP_TRACK_OWNERS
+__fastcall
+#endif
+MyAllocatePool(
+    ULONG type,
+    ULONG size
+#ifdef MY_HEAP_TRACK_OWNERS
+   ,USHORT Src,
+    USHORT Line
+#endif
+#ifdef MY_HEAP_TRACK_REF
+   ,PCHAR Tag
+#endif //MY_HEAP_TRACK_REF
+    )
+{
+    ULONG i;
+    ULONG addr;
+
+//    KdPrint(("MemFrames: %x\n",FrameCount));
+
+    if(!size || (size > MY_HEAP_FRAME_SIZE)) return NULL;
+
+#ifdef DUMP_MEM_FRAMES2
+    if(MyDumpMem)
+        MyAllocDumpFrames();
+#endif
+
+    LockMemoryManager();
+    for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
+        if( FrameList[i].Frame &&
+           (FrameList[i].Type == type) &&
+           (addr = (ULONG)MyAllocatePoolInFrame(i,size
+#ifdef MY_HEAP_TRACK_OWNERS
+                                                      ,Src,Line
+#endif
+#ifdef MY_HEAP_TRACK_REF
+                                                               ,Tag
+#endif //MY_HEAP_TRACK_REF
+                                                                )) ) {
+
+#ifdef UDF_DBG
+//            if(addr >= (ULONG)BreakAddr && addr < sizeof(UDF_FILE_INFO) + (ULONG)BreakAddr) {
+//            if(addr<=(ULONG)BreakAddr && addr+sizeof(UDF_FILE_INFO) > (ULONG)BreakAddr) {
+//                KdPrint(("ERROR !!! Allocating in examined block\n"));
+//                KdPrint(("addr %x\n", addr));
+//                MyAllocDumpFrame(i);
+//                BrutePoint();
+//            }
+#endif //UDF_DBG
+
+            UnlockMemoryManager();
+            DbgTouch((PVOID)addr);
+            return (PCHAR)addr;
+        }
+    }
+#ifdef DUMP_MEM_FRAMES2
+    MyAllocDumpFrames();
+#endif
+    addr = 0;
+    for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
+//        MyAllocDumpFrame(i);
+        if(!(FrameList[i].Frame)) {
+            MyAllocInitFrame(type, i);
+            if(FrameList[i].Frame &&
+               (addr = (ULONG)MyAllocatePoolInFrame(i,size
+#ifdef MY_HEAP_TRACK_OWNERS
+                                                           ,Src,Line
+#endif
+#ifdef MY_HEAP_TRACK_REF
+                                                                    ,Tag
+#endif //MY_HEAP_TRACK_REF
+                                                                     )) ) {
+
+#ifdef UDF_DBG
+//                if(addr >= (ULONG)BreakAddr && addr < sizeof(UDF_FILE_INFO) + (ULONG)BreakAddr) {
+//                if(addr<=(ULONG)BreakAddr && addr+sizeof(UDF_FILE_INFO) > (ULONG)BreakAddr) {
+//                    KdPrint(("ERROR !!! Allocating in examined block\n"));
+//                    KdPrint(("addr %x\n", addr));
+//                    MyAllocDumpFrame(i);
+//                    BrutePoint();
+//                }
+//            } else {
+//                addr = 0;
+#endif //UDF_DBG
+            }
+#ifdef DUMP_MEM_FRAMES2
+            MyAllocDumpFrames();
+#endif
+            break;
+        }
+    }
+    UnlockMemoryManager();
+    return (PCHAR)addr;
+} // end MyAllocatePool()
+
+LONG
+__fastcall
+MyFindFrameByAddr(
+    PCHAR addr
+    )
+{
+    ULONG i;
+//    ULONG j;
+    PMEM_ALLOC_DESC Allocs;
+
+    for(i=0;i<=LastFrame; i++) {
+        if( (Allocs = FrameList[i].Frame) &&
+            (Allocs[0].Addr <= (ULONG)addr) &&
+            (Allocs[0].Addr + MY_HEAP_FRAME_SIZE > (ULONG)addr) ) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+VOID
+__fastcall
+MyFreePool(
+    PCHAR addr
+    )
+{
+    LONG i;
+
+//    KdPrint(("MemFrames: %x\n",FrameCount));
+
+    LockMemoryManager();
+    i = MyFindFrameByAddr(addr);
+    if(i < 0) {
+        UnlockMemoryManager();
+        KdPrint(("Mem: <<<*** WARNING ***>>> Double deallocation at %x !!!   ;( \n", addr));
+        BrutePoint();
+        return;
+    }
+
+#ifdef UDF_DBG
+            // BreakAddr <= addr < BreakAddr + sizeof(UDF_FILE_INFO)
+//            if((ULONG)addr >= (ULONG)BreakAddr && (ULONG)addr < sizeof(UDF_FILE_INFO) + (ULONG)BreakAddr) {
+//                KdPrint(("Deallocating in examined block\n"));
+//                KdPrint(("addr %x\n", addr));
+//                MyAllocDumpFrame(i);
+//                BrutePoint();
+//                BreakAddr = NULL;
+//            }
+#endif //UDF_DBG
+
+    MyFreePoolInFrame(i,addr);
+/*            for(j=0;j<MY_HEAP_MAX_BLOCKS; j++) {
+        if((Allocs[j].Len & MY_HEAP_FLAG_USED) || (FrameCount<=1)) {
+            return;
+        }
+    }*/
+    if(MyAllocIsFrameFree(FrameList, i)) {
+        MyAllocFreeFrame(i);
+    }
+    UnlockMemoryManager();
+    return;
+} // end MyFreePool()
+
+ULONG
+#ifndef MY_HEAP_TRACK_OWNERS
+__fastcall
+#endif
+MyReallocPool(
+    IN PCHAR addr,
+    IN ULONG OldLength,
+    OUT PCHAR* NewBuff,
+    IN ULONG NewLength
+#ifdef MY_HEAP_TRACK_OWNERS
+   ,USHORT Src,
+    USHORT Line
+#endif
+    )
+{
+    ULONG i;
+    PCHAR new_buff;
+#ifdef MY_HEAP_TRACK_REF
+    PCHAR Tag;
+#endif
+
+//    KdPrint(("MemFrames: %x\n",FrameCount));
+    (*NewBuff) = addr;
+    if(OldLength == NewLength) return OldLength;
+
+    if(!NewLength) {
+        BrutePoint();
+        return 0;
+    }
+
+    LockMemoryManager();
+    i = MyFindFrameByAddr(addr);
+    if(i < 0) {
+        UnlockMemoryManager();
+        KdPrint(("Mem: <<<*** WARNING ***>>> Double deallocation at %x !!!   ;( \n", addr));
+        BrutePoint();
+        return 0;
+    }
+
+    if(MyResizePoolInFrame(i,addr,NewLength
+#ifdef MY_HEAP_TRACK_REF
+                                           , &Tag
+#endif
+                                                  )) {
+#ifdef CHECK_ALLOC_FRAMES
+MyAllocCheck(i);
+#endif
+
+        (*NewBuff) = addr;
+        DbgTouch((PVOID)addr);
+        UnlockMemoryManager();
+        return NewLength;
+    }
+
+    new_buff = MyAllocatePool(FrameList[i].Type, MyAlignSize__(NewLength)
+#ifdef MY_HEAP_TRACK_OWNERS
+                                                                         ,Src,Line
+#endif
+#ifdef MY_HEAP_TRACK_REF
+                                                                                  ,Tag
+#endif //MY_HEAP_TRACK_REF
+                                                                                   );
+    if(!new_buff) {
+        UnlockMemoryManager();
+        return 0;
+    }
+
+    if(OldLength > NewLength) OldLength = NewLength;
+    RtlCopyMemory(new_buff, addr, OldLength);
+
+    MyFreePoolInFrame(i,addr);
+
+    if(MyAllocIsFrameFree(FrameList, i)) {
+        MyAllocFreeFrame(i);
+    }
+    UnlockMemoryManager();
+
+    DbgTouch((PVOID)new_buff);
+    (*NewBuff) = new_buff;
+    return OldLength;
+
+} // end MyReallocPool()
+
+#ifdef UDF_DBG
+LONG
+MyFindMemDescByRangeInFrame(
+    ULONG Frame,
+    PCHAR addr
+    )
+{
+    ULONG i;
+    ULONG left;
+    ULONG right;
+    PMEM_ALLOC_DESC Allocs;
+    ULONG curaddr;
+    ULONG curlen;
+
+    Allocs = FrameList[Frame].Frame;
+//    i = FrameList[Frame].LastUsed >> 1;
+//    KdPrint(("Mem: Freeing %x\n", (ULONG)addr)); DEADDA7A
+//    for(i=0;i<MY_HEAP_MAX_BLOCKS;i++) {
+    left = 0;
+    right = FrameList[Frame].LastUsed;
+    if(!right && FrameList[Frame].FirstFree)
+        right = 1;
+    while(left != right) {
+        i = (right + left) >> 1;
+        curaddr = Allocs[i].Addr;
+        curlen = Allocs[i].Len;
+        if( (curlen & MY_HEAP_FLAG_USED) &&
+            (curaddr <= (ULONG)addr) &&
+            ((curaddr+(curlen & MY_HEAP_FLAG_LEN_MASK)) > (ULONG)addr) ) {
+FIF_Found:
+            return i;
+        }
+        if(right - left == 1) {
+            if( (Allocs[i+1].Len & MY_HEAP_FLAG_USED) && (Allocs[i+1].Addr == (ULONG)addr) ) {
+                i++;
+                goto FIF_Found;
+            }
+            break;
+        }
+        if(Allocs[i].Addr && (Allocs[i].Addr < (ULONG)addr)) {
+            left = i;
+        } else {
+            right = i;
+        }
+    }
+    return -1;
+} // end MyFindMemDescByRangeInFrame()
+
+LONG
+MyFindMemBaseByAddr(
+    PCHAR addr
+    )
+{
+    ULONG Frame, Base, i;
+
+    LockMemoryManager();
+    Frame = MyFindFrameByAddr(addr);
+    if(Frame < 0) {
+        UnlockMemoryManager();
+        KdPrint(("Mem: <<<*** WARNING ***>>> Unknown base for %x !!!   ;( \n", addr));
+        BrutePoint();
+        return -1;
+    }
+    i = MyFindMemDescByRangeInFrame(Frame, addr);
+    Base = FrameList[Frame].Frame[i].Addr;
+    UnlockMemoryManager();
+    return Base;
+} // end MyFindMemBaseByAddr()
+#endif //UDF_DBG
+
+BOOLEAN
+MyAllocInit(VOID)
+{
+    RtlZeroMemory(&FrameList, sizeof(FrameList));
+    if(!OS_SUCCESS(InitLockMemoryManager())) {
+       return FALSE;
+    }
+    MyAllocInitFrame(NonPagedPool, 0);
+    LastFrame = 0;
+    return (MyMemInitialized = TRUE);
+} // end MyAllocInit()
+
+VOID
+MyAllocRelease(VOID)
+{
+    ULONG i;
+    PMEM_ALLOC_DESC Allocs;
+
+    if(!MyMemInitialized)
+        return;
+    LockMemoryManager();
+    for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
+        if(Allocs = FrameList[i].Frame) {
+            MyAllocFreeFrame(i);
+        }
+    }
+    RtlZeroMemory(&FrameList, sizeof(FrameList));
+    UnlockMemoryManager();
+    DeinitLockMemoryManager();
+    MyMemInitialized = FALSE;
+} // end MyAllocRelease()
+
+#endif //MY_USE_INTERNAL_MEMMANAGER
diff --git a/reactos/drivers/filesystems/udfs/Include/mem_tools.h b/reactos/drivers/filesystems/udfs/Include/mem_tools.h
new file mode 100644 (file)
index 0000000..db41159
--- /dev/null
@@ -0,0 +1,304 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifndef __MY_MEM_TOOLS_H__
+#define __MY_MEM_TOOLS_H__
+
+#define MY_HEAP_FLAG_USED       0x00000001
+#define MY_HEAP_FLAG_LEN_MASK   0xfffffffe
+
+#define MyFreeMemoryAndPointer(ptr) \
+    if(ptr) {                   \
+        MyFreePool__(ptr);      \
+        ptr = NULL;             \
+    }
+
+#define MY_USE_ALIGN
+//#define MY_MEM_BOUNDS_CHECK
+
+typedef struct _MEM_ALLOC_DESC {
+    ULONG Addr;
+    ULONG Len;
+#ifdef MY_HEAP_TRACK_OWNERS
+    USHORT Src;
+    USHORT Line;
+#endif
+#ifdef MY_HEAP_TRACK_REF
+//    PCHAR Ref;
+    PCHAR Tag;
+#endif 
+} MEM_ALLOC_DESC, *PMEM_ALLOC_DESC;
+
+typedef struct _MEM_FRAME_ALLOC_DESC {
+    PMEM_ALLOC_DESC Frame;
+    ULONG LastUsed;
+    ULONG FirstFree;
+    ULONG Type;
+} MEM_FRAME_ALLOC_DESC, *PMEM_FRAME_ALLOC_DESC;
+
+extern PCHAR BreakAddr;
+extern ULONG MemTotalAllocated;
+
+#define MY_HEAP_FRAME_SIZE          (256*1024)
+#define MY_HEAP_MAX_FRAMES          512
+#define MY_HEAP_MAX_BLOCKS          4*1024  // blocks per frame
+
+#ifdef USE_THREAD_HEAPS
+//extern HANDLE MemLock;
+extern "C" VOID ExInitThreadPools();
+extern "C" VOID ExDeInitThreadPools();
+extern "C" VOID ExFreeThreadPool();
+#endif //USE_THREAD_HEAPS
+
+// Mem
+BOOLEAN MyAllocInit(VOID);
+VOID MyAllocRelease(VOID);
+#ifdef MY_HEAP_TRACK_OWNERS
+PCHAR MyAllocatePool(ULONG Type, ULONG size, USHORT Src, USHORT Line
+  #ifdef MY_HEAP_TRACK_REF
+                    ,PCHAR Tag
+  #endif //MY_HEAP_TRACK_REF
+      );
+ULONG MyReallocPool( PCHAR addr, ULONG OldLength, PCHAR* NewBuff, ULONG NewLength, USHORT Src, USHORT Line);
+#else
+PCHAR __fastcall MyAllocatePool(ULONG Type, ULONG size
+  #ifdef MY_HEAP_TRACK_REF
+                    ,PCHAR Tag
+  #endif //MY_HEAP_TRACK_REF
+      );
+ULONG __fastcall MyReallocPool( PCHAR addr, ULONG OldLength, PCHAR* NewBuff, ULONG NewLength);
+#endif
+VOID __fastcall MyFreePool(PCHAR addr);
+
+#ifdef MY_HEAP_CHECK_BOUNDS
+  #define MY_HEAP_ALIGN             63
+#else
+  #define MY_HEAP_ALIGN             63
+#endif
+#define PAGE_SIZE_ALIGN             (PAGE_SIZE - 1)
+
+#define AlignToPageSize(size) (((size)+PAGE_SIZE_ALIGN)&(~PAGE_SIZE_ALIGN))
+#define MyAlignSize__(size) (((size)+MY_HEAP_ALIGN)&(~MY_HEAP_ALIGN))
+#ifdef MY_HEAP_FORCE_NONPAGED
+#define MyFixMemType(type)          NonPagedPool
+#else //MY_HEAP_FORCE_NONPAGED
+#define MyFixMemType(type)          (type)
+#endif //MY_HEAP_FORCE_NONPAGED
+
+#ifdef MY_USE_INTERNAL_MEMMANAGER
+
+#ifdef MY_HEAP_TRACK_OWNERS
+  #ifdef MY_HEAP_TRACK_REF
+    #define MyAllocatePool__(type,size) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__, NULL)
+    #define MyAllocatePoolTag__(type,size,tag) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__, (PCHAR)(tag))
+  #else
+    #define MyAllocatePool__(type,size) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__)
+    #define MyAllocatePoolTag__(type,size,tag) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__)
+  #endif //MY_HEAP_TRACK_REF
+#else //MY_HEAP_TRACK_OWNERS
+  #ifdef MY_HEAP_TRACK_REF
+    #define MyAllocatePool__(type,size) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size), NULL)
+    #define MyAllocatePoolTag__(type,size,tag) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size), (PCHAR)(tag))
+  #else
+    #define MyAllocatePool__(type,size) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size))
+    #define MyAllocatePoolTag__(type,size,tag) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size))
+  #endif //MY_HEAP_TRACK_REF
+#endif //MY_HEAP_TRACK_OWNERS
+
+#define MyFreePool__(addr) MyFreePool((PCHAR)(addr))
+
+#ifdef MY_HEAP_TRACK_OWNERS
+#define MyReallocPool__(addr, len, pnewaddr, newlen) MyReallocPool((PCHAR)(addr), MyAlignSize__(len), pnewaddr, MyAlignSize__(newlen), UDF_BUG_CHECK_ID, __LINE__)
+#else
+#define MyReallocPool__(addr, len, pnewaddr, newlen) MyReallocPool((PCHAR)(addr), MyAlignSize__(len), pnewaddr, MyAlignSize__(newlen))
+#endif
+
+#ifdef UDF_DBG
+LONG
+MyFindMemBaseByAddr(
+    PCHAR addr
+    );
+
+#define MyCheckArray(base, index) \
+    ASSERT(MyFindMemBaseByAddr((PCHAR)(base)) == MyFindMemBaseByAddr((PCHAR)(base+(index))))
+
+#else
+#define MyCheckArray(base, index)
+#endif //UDF_DBG
+
+
+#else //MY_USE_INTERNAL_MEMMANAGER
+
+#ifndef MY_USE_ALIGN
+#undef  MyAlignSize__
+#define MyAlignSize__(size) (size)
+#endif
+
+BOOLEAN inline MyAllocInit(VOID) {return TRUE;}
+#define MyAllocRelease()
+
+#ifndef MY_MEM_BOUNDS_CHECK
+
+  #ifdef TRACK_SYS_ALLOC_CALLERS
+    #define MyAllocatePool__(type,size) DebugAllocatePool(NonPagedPool,MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__)
+    #define MyAllocatePoolTag__(type,size,tag) DebugAllocatePool(NonPagedPool,MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__)
+  #else //TRACK_SYS_ALLOC_CALLERS
+    #define MyAllocatePool__(type,size) DbgAllocatePoolWithTag(NonPagedPool,MyAlignSize__(size), 'fNWD')
+    #define MyAllocatePoolTag__(type,size,tag) DbgAllocatePoolWithTag(NonPagedPool,MyAlignSize__(size), tag)
+  #endif //TRACK_SYS_ALLOC_CALLERS
+  #define MyFreePool__(addr) DbgFreePool((PCHAR)(addr))
+
+#else //MY_MEM_BOUNDS_CHECK
+
+  #ifdef TRACK_SYS_ALLOC_CALLERS
+    #define MyAllocatePool_(type,size) DebugAllocatePool(NonPagedPool,MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__)
+    #define MyAllocatePoolTag_(type,size,tag) DebugAllocatePool(NonPagedPool,MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__)
+  #else //TRACK_SYS_ALLOC_CALLERS
+    #define MyAllocatePool_(type,size) DbgAllocatePoolWithTag(NonPagedPool,MyAlignSize__(size), 'mNWD')
+    #define MyAllocatePoolTag_(type,size,tag) DbgAllocatePoolWithTag(NonPagedPool,MyAlignSize__(size), tag)
+  #endif //TRACK_SYS_ALLOC_CALLERS
+  #define MyFreePool_(addr) DbgFreePool((PCHAR)(addr))
+
+#define MyAllocatePool__(type,size) MyAllocatePoolTag__(type,size,'mNWD')
+
+/*
+PVOID inline MyAllocatePool__(ULONG type, ULONG len) {
+    PCHAR newaddr;
+    ULONG i;
+//    newaddr = (PCHAR)MyAllocatePool_(type, len+MY_HEAP_ALIGN+1);
+#ifdef TRACK_SYS_ALLOC_CALLERS
+    newaddr = (PCHAR)DebugAllocatePool(type,len+MY_HEAP_ALIGN+1, 0x202, __LINE__);
+#else //TRACK_SYS_ALLOC_CALLERS
+    newaddr = (PCHAR)MyAllocatePool_(type,len+MY_HEAP_ALIGN+1); 
+#endif //TRACK_SYS_ALLOC_CALLERS
+    if(!newaddr)
+        return NULL;
+    for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+        newaddr[len+i] = (UCHAR)('A'+i);
+    }
+    return newaddr;
+}
+*/
+
+PVOID inline MyAllocatePoolTag__(ULONG type, ULONG len, /*PCHAR*/ULONG tag) {
+    PCHAR newaddr;
+    ULONG i;
+//    newaddr = (PCHAR)MyAllocatePoolTag_(type, len+MY_HEAP_ALIGN+1, tag);
+#ifdef TRACK_SYS_ALLOC_CALLERS
+    newaddr = (PCHAR)DebugAllocatePool(type,len+MY_HEAP_ALIGN+1, 0x202, __LINE__);
+#else //TRACK_SYS_ALLOC_CALLERS
+    newaddr = (PCHAR)MyAllocatePoolTag_(type,len+MY_HEAP_ALIGN+1, tag); 
+#endif //TRACK_SYS_ALLOC_CALLERS
+    if(!newaddr)
+        return NULL;
+    for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+        newaddr[len+i] = (UCHAR)('A'+i);
+    }
+    return newaddr;
+}
+
+VOID inline MyFreePool__(PVOID addr) {
+    PCHAR newaddr;
+//    ULONG i;
+    newaddr = (PCHAR)addr;
+    if(!newaddr) {
+        __asm int 3;
+        return;
+    }
+/*
+    for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+        if(newaddr[len+i] != (UCHAR)('A'+i)) {
+            __asm int 3;
+            break;
+        }
+    }
+*/
+    MyFreePool_(newaddr);
+}
+
+#endif //MY_MEM_BOUNDS_CHECK
+
+ULONG inline MyReallocPool__(PCHAR addr, ULONG len, PCHAR *pnewaddr, ULONG newlen) {
+    ULONG _len, _newlen;
+    _newlen = MyAlignSize__(newlen);
+    _len = MyAlignSize__(len);
+    PCHAR newaddr;
+
+    ASSERT(len && newlen);
+
+#ifdef MY_MEM_BOUNDS_CHECK
+    ULONG i;
+
+    for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+        if((UCHAR)(addr[len+i]) != (UCHAR)('A'+i)) {
+            __asm int 3;
+            break;
+        }
+    }
+#endif //MY_MEM_BOUNDS_CHECK
+    
+    if ((_newlen != _len)
+#ifdef MY_MEM_BOUNDS_CHECK
+        || TRUE
+#endif //MY_MEM_BOUNDS_CHECK
+    ) { 
+#ifdef TRACK_SYS_ALLOC_CALLERS
+        newaddr = (PCHAR)DebugAllocatePool(NonPagedPool,_newlen, 0x202, __LINE__);
+#else //TRACK_SYS_ALLOC_CALLERS
+        newaddr = (PCHAR)MyAllocatePool__(NonPagedPool,_newlen); 
+#endif //TRACK_SYS_ALLOC_CALLERS
+        if (!newaddr) {
+            __debugbreak();
+            *pnewaddr = addr;
+            return 0;
+        }
+#ifdef MY_MEM_BOUNDS_CHECK
+        for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+            newaddr[newlen+i] = (UCHAR)('A'+i);
+        }
+#endif //MY_MEM_BOUNDS_CHECK
+        *pnewaddr = newaddr;
+        if(_newlen <= _len) {
+            RtlCopyMemory(newaddr, addr, newlen);
+        } else {
+            RtlCopyMemory(newaddr, addr, len);
+            RtlZeroMemory(newaddr+len, newlen - len);
+        }
+#ifdef MY_MEM_BOUNDS_CHECK
+        for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+            if((UCHAR)(newaddr[newlen+i]) != (UCHAR)('A'+i)) {
+                __asm int 3;
+                break;
+            }
+        }
+#endif //MY_MEM_BOUNDS_CHECK
+
+        MyFreePool__(addr); 
+    } else {
+        *pnewaddr = addr;
+    }
+    if(newlen > len) {
+        //RtlZeroMemory(newaddr+len, newlen - len);
+    }
+/*
+#ifdef MY_MEM_BOUNDS_CHECK
+    for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+        newaddr[newlen+i] = (UCHAR)('A'+i);
+    }
+#endif //MY_MEM_BOUNDS_CHECK
+*/
+    return newlen;
+}
+
+#ifndef MY_USE_ALIGN
+#undef  MyAlignSize__
+#define MyAlignSize__(size) (((size)+MY_HEAP_ALIGN)&(~MY_HEAP_ALIGN))
+#endif
+
+#define MyCheckArray(base, index)
+
+#endif // MY_USE_INTERNAL_MEMMANAGER
+
+#endif // __MY_MEM_TOOLS_H__
diff --git a/reactos/drivers/filesystems/udfs/Include/misc_common.cpp b/reactos/drivers/filesystems/udfs/Include/misc_common.cpp
new file mode 100644 (file)
index 0000000..a99aeb6
--- /dev/null
@@ -0,0 +1,32 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+
+VOID
+UDFSetModified(
+    IN PVCB        Vcb
+    )
+{
+    if(UDFInterlockedIncrement((PLONG)&(Vcb->Modified)) & 0x80000000)
+        Vcb->Modified = 2;
+} // end UDFSetModified()
+
+VOID
+UDFPreClrModified(
+    IN PVCB        Vcb
+    )
+{
+    Vcb->Modified = 1;
+} // end UDFPreClrModified()
+
+VOID
+UDFClrModified(
+    IN PVCB        Vcb
+    )
+{
+    KdPrint(("ClrModified\n"));
+    UDFInterlockedDecrement((PLONG)&(Vcb->Modified));
+} // end UDFClrModified()
+
diff --git a/reactos/drivers/filesystems/udfs/Include/mountmgr.h b/reactos/drivers/filesystems/udfs/Include/mountmgr.h
new file mode 100644 (file)
index 0000000..b2703cb
--- /dev/null
@@ -0,0 +1,169 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+/*++
+
+Copyright (c) 1997-1999  Microsoft Corporation
+
+Module Name:
+
+    mountmgr.h
+
+Abstract:
+
+    This file defines the external mount point interface for administering
+    mount points.
+
+Author:
+
+    norbertk
+
+Revision History:
+
+--*/
+
+#ifndef _MOUNTMGR_
+#define _MOUNTMGR_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#ifndef FAR
+#define FAR
+#endif
+
+
+#define MOUNTMGR_DEVICE_NAME        L"\\Device\\MountPointManager"
+#define MOUNTMGR_DOS_DEVICE_NAME    L"\\\\.\\MountPointManager"
+
+#define MOUNTMGRCONTROLTYPE  ((ULONG) 'm')
+#define MOUNTDEVCONTROLTYPE  ((ULONG) 'M')
+
+//
+// These are the IOCTLs supported by the mount point manager.
+//
+
+#define IOCTL_MOUNTMGR_CREATE_POINT                 CTL_CODE(MOUNTMGRCONTROLTYPE, 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_DELETE_POINTS                CTL_CODE(MOUNTMGRCONTROLTYPE, 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_QUERY_POINTS                 CTL_CODE(MOUNTMGRCONTROLTYPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY         CTL_CODE(MOUNTMGRCONTROLTYPE, 3, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER            CTL_CODE(MOUNTMGRCONTROLTYPE, 4, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_AUTO_DL_ASSIGNMENTS          CTL_CODE(MOUNTMGRCONTROLTYPE, 5, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED   CTL_CODE(MOUNTMGRCONTROLTYPE, 6, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED   CTL_CODE(MOUNTMGRCONTROLTYPE, 7, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_CHANGE_NOTIFY                CTL_CODE(MOUNTMGRCONTROLTYPE, 8, METHOD_BUFFERED, FILE_READ_ACCESS)
+#define IOCTL_MOUNTMGR_KEEP_LINKS_WHEN_OFFLINE      CTL_CODE(MOUNTMGRCONTROLTYPE, 9, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_CHECK_UNPROCESSED_VOLUMES    CTL_CODE(MOUNTMGRCONTROLTYPE, 10, METHOD_BUFFERED, FILE_READ_ACCESS)
+#define IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION  CTL_CODE(MOUNTMGRCONTROLTYPE, 11, METHOD_BUFFERED, FILE_READ_ACCESS)
+
+//
+// Input structure for IOCTL_MOUNTMGR_CREATE_POINT.
+//
+
+typedef struct _MOUNTMGR_CREATE_POINT_INPUT {
+    USHORT  SymbolicLinkNameOffset;
+    USHORT  SymbolicLinkNameLength;
+    USHORT  DeviceNameOffset;
+    USHORT  DeviceNameLength;
+} MOUNTMGR_CREATE_POINT_INPUT, *PMOUNTMGR_CREATE_POINT_INPUT;
+
+//
+// Input structure for IOCTL_MOUNTMGR_DELETE_POINTS,
+// IOCTL_MOUNTMGR_QUERY_POINTS, and IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY.
+//
+
+typedef struct _MOUNTMGR_MOUNT_POINT {
+    ULONG   SymbolicLinkNameOffset;
+    USHORT  SymbolicLinkNameLength;
+    ULONG   UniqueIdOffset;
+    USHORT  UniqueIdLength;
+    ULONG   DeviceNameOffset;
+    USHORT  DeviceNameLength;
+} MOUNTMGR_MOUNT_POINT, *PMOUNTMGR_MOUNT_POINT;
+
+//
+// Output structure for IOCTL_MOUNTMGR_DELETE_POINTS,
+// IOCTL_MOUNTMGR_QUERY_POINTS, and IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY.
+//
+
+typedef struct _MOUNTMGR_MOUNT_POINTS {
+    ULONG                   Size;
+    ULONG                   NumberOfMountPoints;
+    MOUNTMGR_MOUNT_POINT    MountPoints[1];
+} MOUNTMGR_MOUNT_POINTS, *PMOUNTMGR_MOUNT_POINTS;
+
+//
+// Input structure for IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER.
+//
+
+typedef struct _MOUNTMGR_DRIVE_LETTER_TARGET {
+    USHORT  DeviceNameLength;
+    WCHAR   DeviceName[1];
+} MOUNTMGR_DRIVE_LETTER_TARGET, *PMOUNTMGR_DRIVE_LETTER_TARGET;
+
+//
+// Output structure for IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER.
+//
+
+typedef struct _MOUNTMGR_DRIVE_LETTER_INFORMATION {
+    BOOLEAN DriveLetterWasAssigned;
+    UCHAR   CurrentDriveLetter;
+} MOUNTMGR_DRIVE_LETTER_INFORMATION, *PMOUNTMGR_DRIVE_LETTER_INFORMATION;
+
+//
+// Input structure for IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED and
+// IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED.
+//
+
+typedef struct _MOUNTMGR_VOLUME_MOUNT_POINT {
+    USHORT  SourceVolumeNameOffset;
+    USHORT  SourceVolumeNameLength;
+    USHORT  TargetVolumeNameOffset;
+    USHORT  TargetVolumeNameLength;
+} MOUNTMGR_VOLUME_MOUNT_POINT, *PMOUNTMGR_VOLUME_MOUNT_POINT;
+
+//
+// Input structure for IOCTL_MOUNTMGR_CHANGE_NOTIFY.
+// Output structure for IOCTL_MOUNTMGR_CHANGE_NOTIFY.
+//
+
+typedef struct _MOUNTMGR_CHANGE_NOTIFY_INFO {
+    ULONG   EpicNumber;
+} MOUNTMGR_CHANGE_NOTIFY_INFO, *PMOUNTMGR_CHANGE_NOTIFY_INFO;
+
+//
+// Input structure for IOCTL_MOUNTMGR_KEEP_LINKS_WHEN_OFFLINE and
+// IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION.
+//
+
+typedef struct _MOUNTMGR_TARGET_NAME {
+    USHORT  DeviceNameLength;
+    WCHAR   DeviceName[1];
+} MOUNTMGR_TARGET_NAME, *PMOUNTMGR_TARGET_NAME;
+
+//
+// The following IOCTL is supported by mounted devices.
+//
+
+#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME    CTL_CODE(MOUNTDEVCONTROLTYPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+//
+// Output structure for IOCTL_MOUNTDEV_QUERY_DEVICE_NAME.
+//
+
+typedef struct _MOUNTDEV_NAME {
+    USHORT  NameLength;
+    WCHAR   Name[1];
+} MOUNTDEV_NAME, *PMOUNTDEV_NAME;
+
+//
+// Devices that wish to be mounted should report this GUID in
+// IoRegisterDeviceInterface.
+//
+
+//DEFINE_GUID(MOUNTDEV_MOUNTED_DEVICE_GUID, 0x53f5630d, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
+
+#endif
+
diff --git a/reactos/drivers/filesystems/udfs/Include/nt_native.h b/reactos/drivers/filesystems/udfs/Include/nt_native.h
new file mode 100644 (file)
index 0000000..533a88e
--- /dev/null
@@ -0,0 +1,1951 @@
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+//======================================================================
+//
+// NT_Native.h
+//
+//======================================================================
+
+#ifndef __NT_NATIVE_DEFS__H__
+#define __NT_NATIVE_DEFS__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif //__cplusplus
+
+#include <excpt.h>
+#include <ntdef.h>
+#include <ntstatus.h>
+#include <string.h>
+#include <DEVIOCTL.H>
+#include <NTDDSTOR.H>
+#include <NTDDDISK.H>
+
+typedef struct _KTHREAD *PKTHREAD;
+typedef struct _ETHREAD *PETHREAD;
+typedef struct _EPROCESS *PEPROCESS;
+typedef struct _PEB *PPEB;
+typedef struct _KINTERRUPT *PKINTERRUPT;
+typedef struct _IO_TIMER *PIO_TIMER;
+typedef struct _OBJECT_TYPE *POBJECT_TYPE;
+typedef struct _CALLBACK_OBJECT *PCALLBACK_OBJECT;
+typedef struct _DEVICE_HANDLER_OBJECT *PDEVICE_HANDLER_OBJECT;
+typedef struct _BUS_HANDLER *PBUS_HANDLER;
+
+
+typedef ULONG ACCESS_MASK;
+typedef ACCESS_MASK *PACCESS_MASK;
+
+#define BOOL  BOOLEAN
+#define DWORD ULONG
+#define LPVOID PVOID
+#define LPDWORD PULONG
+
+#define APIENTRY __stdcall
+
+#define FASTCALL _fastcall
+
+// end_winnt
+//
+//  The following are masks for the predefined standard access types
+//
+
+#define DELETE                           (0x00010000L)
+#define READ_CONTROL                     (0x00020000L)
+#define WRITE_DAC                        (0x00040000L)
+#define WRITE_OWNER                      (0x00080000L)
+#define SYNCHRONIZE                      (0x00100000L)
+
+#define STANDARD_RIGHTS_REQUIRED         (0x000F0000L)
+
+#define STANDARD_RIGHTS_READ             (READ_CONTROL)
+#define STANDARD_RIGHTS_WRITE            (READ_CONTROL)
+#define STANDARD_RIGHTS_EXECUTE          (READ_CONTROL)
+
+#define STANDARD_RIGHTS_ALL              (0x001F0000L)
+
+#define SPECIFIC_RIGHTS_ALL              (0x0000FFFFL)
+
+//
+// AccessSystemAcl access type
+//
+
+#define ACCESS_SYSTEM_SECURITY           (0x01000000L)
+
+//
+// MaximumAllowed access type
+//
+
+#define MAXIMUM_ALLOWED                  (0x02000000L)
+
+//
+//  These are the generic rights.
+//
+
+#define GENERIC_READ                     (0x80000000L)
+#define GENERIC_WRITE                    (0x40000000L)
+#define GENERIC_EXECUTE                  (0x20000000L)
+#define GENERIC_ALL                      (0x10000000L)
+
+
+//
+// Subroutines for dealing with the Registry
+//
+
+typedef NTSTATUS (*PRTL_QUERY_REGISTRY_ROUTINE)(
+    IN PWSTR ValueName,
+    IN ULONG ValueType,
+    IN PVOID ValueData,
+    IN ULONG ValueLength,
+    IN PVOID Context,
+    IN PVOID EntryContext
+    );
+
+typedef struct _RTL_QUERY_REGISTRY_TABLE {
+    PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
+    ULONG Flags;
+    PWSTR Name;
+    PVOID EntryContext;
+    ULONG DefaultType;
+    PVOID DefaultData;
+    ULONG DefaultLength;
+
+} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;
+
+
+//
+// The following flags specify how the Name field of a RTL_QUERY_REGISTRY_TABLE
+// entry is interpreted.  A NULL name indicates the end of the table.
+//
+
+#define RTL_QUERY_REGISTRY_SUBKEY   0x00000001  // Name is a subkey and remainder of
+                                                // table or until next subkey are value
+                                                // names for that subkey to look at.
+
+#define RTL_QUERY_REGISTRY_TOPKEY   0x00000002  // Reset current key to original key for
+                                                // this and all following table entries.
+
+#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004  // Fail if no match found for this table
+                                                // entry.
+
+#define RTL_QUERY_REGISTRY_NOVALUE  0x00000008  // Used to mark a table entry that has no
+                                                // value name, just wants a call out, not
+                                                // an enumeration of all values.
+
+#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010  // Used to suppress the expansion of
+                                                // REG_MULTI_SZ into multiple callouts or
+                                                // to prevent the expansion of environment
+                                                // variable values in REG_EXPAND_SZ
+
+#define RTL_QUERY_REGISTRY_DIRECT   0x00000020  // QueryRoutine field ignored.  EntryContext
+                                                // field points to location to store value.
+                                                // For null terminated strings, EntryContext
+                                                // points to UNICODE_STRING structure that
+                                                // that describes maximum size of buffer.
+                                                // If .Buffer field is NULL then a buffer is
+                                                // allocated.
+                                                //
+
+#define RTL_QUERY_REGISTRY_DELETE   0x00000040  // Used to delete value keys after they
+                                                // are queried.
+
+//
+// The following values for the RelativeTo parameter determine what the
+// Path parameter to RtlQueryRegistryValues is relative to.
+//
+
+#define RTL_REGISTRY_ABSOLUTE     0   // Path is a full path
+#define RTL_REGISTRY_SERVICES     1   // \Registry\Machine\System\CurrentControlSet\Services
+#define RTL_REGISTRY_CONTROL      2   // \Registry\Machine\System\CurrentControlSet\Control
+#define RTL_REGISTRY_WINDOWS_NT   3   // \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion
+#define RTL_REGISTRY_DEVICEMAP    4   // \Registry\Machine\Hardware\DeviceMap
+#define RTL_REGISTRY_USER         5   // \Registry\User\CurrentUser
+#define RTL_REGISTRY_MAXIMUM      6
+#define RTL_REGISTRY_HANDLE       0x40000000    // Low order bits are registry handle
+#define RTL_REGISTRY_OPTIONAL     0x80000000    // Indicates the key node is optional
+
+
+
+NTSYSAPI                                            
+NTSTATUS                                            
+NTAPI                                               
+RtlCharToInteger (                                  
+    PCSZ String,                                    
+    ULONG Base,                                     
+    PULONG Value                                    
+    );                                              
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlIntegerToUnicodeString (
+    ULONG Value,
+    ULONG Base,
+    PUNICODE_STRING String
+    );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlUnicodeStringToInteger (
+    PUNICODE_STRING String,
+    ULONG Base,
+    PULONG Value
+    );
+
+\f
+//
+//  String manipulation routines
+//
+
+#ifdef _NTSYSTEM_
+
+#define NLS_MB_CODE_PAGE_TAG NlsMbCodePageTag
+#define NLS_MB_OEM_CODE_PAGE_TAG NlsMbOemCodePageTag
+
+#else
+
+#define NLS_MB_CODE_PAGE_TAG (*NlsMbCodePageTag)
+#define NLS_MB_OEM_CODE_PAGE_TAG (*NlsMbOemCodePageTag)
+
+#endif // _NTSYSTEM_
+
+extern BOOLEAN NLS_MB_CODE_PAGE_TAG;     // TRUE -> Multibyte CP, FALSE -> Singlebyte
+extern BOOLEAN NLS_MB_OEM_CODE_PAGE_TAG; // TRUE -> Multibyte CP, FALSE -> Singlebyte
+
+NTSYSAPI
+VOID
+NTAPI
+RtlInitString(
+    PSTRING DestinationString,
+    PCSZ SourceString
+    );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlInitAnsiString(
+    PANSI_STRING DestinationString,
+    PCSZ SourceString
+    );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlInitUnicodeString(
+    PUNICODE_STRING DestinationString,
+    PCWSTR SourceString
+    );
+
+
+NTSYSAPI
+VOID
+NTAPI
+RtlCopyString(
+    PSTRING DestinationString,
+    PSTRING SourceString
+    );
+
+NTSYSAPI
+CHAR
+NTAPI
+RtlUpperChar (
+    CHAR Character
+    );
+
+NTSYSAPI
+LONG
+NTAPI
+RtlCompareString(
+    PSTRING String1,
+    PSTRING String2,
+    BOOLEAN CaseInSensitive
+    );
+
+NTSYSAPI
+BOOLEAN
+NTAPI
+RtlEqualString(
+    PSTRING String1,
+    PSTRING String2,
+    BOOLEAN CaseInSensitive
+    );
+
+
+NTSYSAPI
+VOID
+NTAPI
+RtlUpperString(
+    PSTRING DestinationString,
+    PSTRING SourceString
+    );
+
+//
+// NLS String functions
+//
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlAnsiStringToUnicodeString(
+    PUNICODE_STRING DestinationString,
+    PANSI_STRING SourceString,
+    BOOLEAN AllocateDestinationString
+    );
+
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlUnicodeStringToAnsiString(
+    PANSI_STRING DestinationString,
+    PUNICODE_STRING SourceString,
+    BOOLEAN AllocateDestinationString
+    );
+
+
+NTSYSAPI
+LONG
+NTAPI
+RtlCompareUnicodeString(
+    PUNICODE_STRING String1,
+    PUNICODE_STRING String2,
+    BOOLEAN CaseInSensitive
+    );
+
+NTSYSAPI
+BOOLEAN
+NTAPI
+RtlEqualUnicodeString(
+    PUNICODE_STRING String1,
+    PUNICODE_STRING String2,
+    BOOLEAN CaseInSensitive
+    );
+
+NTSYSAPI
+BOOLEAN
+NTAPI
+RtlPrefixUnicodeString(
+    IN PUNICODE_STRING String1,
+    IN PUNICODE_STRING String2,
+    IN BOOLEAN CaseInSensitive
+    );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlUpcaseUnicodeString(
+    PUNICODE_STRING DestinationString,
+    PUNICODE_STRING SourceString,
+    BOOLEAN AllocateDestinationString
+    );
+
+
+NTSYSAPI
+VOID
+NTAPI
+RtlCopyUnicodeString(
+    PUNICODE_STRING DestinationString,
+    PUNICODE_STRING SourceString
+    );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlAppendUnicodeStringToString (
+    PUNICODE_STRING Destination,
+    PUNICODE_STRING Source
+    );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlAppendUnicodeToString (
+    PUNICODE_STRING Destination,
+    PWSTR Source
+    );
+
+
+NTSYSAPI
+VOID
+NTAPI
+RtlFreeUnicodeString(
+    PUNICODE_STRING UnicodeString
+    );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlFreeAnsiString(
+    PANSI_STRING AnsiString
+    );
+
+
+NTSYSAPI
+ULONG
+NTAPI
+RtlxAnsiStringToUnicodeSize(
+    PANSI_STRING AnsiString
+    );
+
+//
+//  NTSYSAPI
+//  ULONG
+//  NTAPI
+//  RtlAnsiStringToUnicodeSize(
+//      PANSI_STRING AnsiString
+//      );
+//
+
+#define RtlAnsiStringToUnicodeSize(STRING) (                 \
+    NLS_MB_CODE_PAGE_TAG ?                                   \
+    RtlxAnsiStringToUnicodeSize(STRING) :                    \
+    ((STRING)->Length + sizeof((UCHAR)NULL)) * sizeof(WCHAR) \
+)
+
+#if DBG
+NTSYSAPI
+VOID
+NTAPI
+RtlAssert(
+    PVOID FailedAssertion,
+    PVOID FileName,
+    ULONG LineNumber,
+    PCHAR Message
+    );
+
+#define ASSERT( exp ) \
+    if (!(exp)) \
+        RtlAssert( #exp, __FILE__, __LINE__, NULL )
+
+#define ASSERTMSG( msg, exp ) \
+    if (!(exp)) \
+        RtlAssert( #exp, __FILE__, __LINE__, msg )
+
+#else
+#define ASSERT( exp )
+#define ASSERTMSG( msg, exp )
+#endif // DBG
+
+//
+// Fast primitives to compare, move, and zero memory
+//
+
+// begin_winnt begin_ntndis
+#if defined(_M_IX86) || defined(_M_MRX000) || defined(_M_ALPHA)
+
+#if defined(_M_MRX000)
+NTSYSAPI
+ULONG
+NTAPI
+RtlEqualMemory (
+    CONST VOID *Source1,
+    CONST VOID *Source2,
+    ULONG Length
+    );
+
+#else
+#define RtlEqualMemory(Destination,Source,Length) (!memcmp((Destination),(Source),(Length)))
+#endif
+
+#define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
+#define RtlCopyMemory(Destination,Source,Length) memcpy((Destination),(Source),(Length))
+#define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
+#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
+
+#else // _M_PPC
+
+NTSYSAPI
+ULONG
+NTAPI
+RtlEqualMemory (
+    CONST VOID *Source1,
+    CONST VOID *Source2,
+    ULONG Length
+    );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlCopyMemory (
+   VOID UNALIGNED *Destination,
+   CONST VOID UNALIGNED *Source,
+   ULONG Length
+   );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlCopyMemory32 (
+   VOID UNALIGNED *Destination,
+   CONST VOID UNALIGNED *Source,
+   ULONG Length
+   );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlMoveMemory (
+   VOID UNALIGNED *Destination,
+   CONST VOID UNALIGNED *Source,
+   ULONG Length
+   );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlFillMemory (
+   VOID UNALIGNED *Destination,
+   ULONG Length,
+   UCHAR Fill
+   );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlZeroMemory (
+   VOID UNALIGNED *Destination,
+   ULONG Length
+   );
+#endif
+// end_winnt end_ntndis
+
+NTSYSAPI
+ULONG
+NTAPI
+RtlCompareMemory (
+    PVOID Source1,
+    PVOID Source2,
+    ULONG Length
+    );
+
+typedef struct _TIME_FIELDS {
+    CSHORT Year;        // range [1601...]
+    CSHORT Month;       // range [1..12]
+    CSHORT Day;         // range [1..31]
+    CSHORT Hour;        // range [0..23]
+    CSHORT Minute;      // range [0..59]
+    CSHORT Second;      // range [0..59]
+    CSHORT Milliseconds;// range [0..999]
+    CSHORT Weekday;     // range [0..6] == [Sunday..Saturday]
+} TIME_FIELDS;
+typedef TIME_FIELDS *PTIME_FIELDS;
+
+
+NTSYSAPI
+VOID
+NTAPI
+RtlTimeToTimeFields (
+    PLARGE_INTEGER Time,
+    PTIME_FIELDS TimeFields
+    );
+
+//
+//  A time field record (Weekday ignored) -> 64 bit Time value
+//
+
+NTSYSAPI
+BOOLEAN
+NTAPI
+RtlTimeFieldsToTime (
+    PTIME_FIELDS TimeFields,
+    PLARGE_INTEGER Time
+    );
+
+//
+//  Define the generic mapping array.  This is used to denote the
+//  mapping of each generic access right to a specific access mask.
+//
+
+typedef struct _GENERIC_MAPPING {
+    ACCESS_MASK GenericRead;
+    ACCESS_MASK GenericWrite;
+    ACCESS_MASK GenericExecute;
+    ACCESS_MASK GenericAll;
+} GENERIC_MAPPING;
+typedef GENERIC_MAPPING *PGENERIC_MAPPING;
+
+//
+// Define the various device type values.  Note that values used by Microsoft
+// Corporation are in the range 0-32767, and 32768-65535 are reserved for use
+// by customers.
+//
+
+#define DEVICE_TYPE ULONG
+
+#define FILE_DEVICE_BEEP                0x00000001
+#define FILE_DEVICE_CD_ROM              0x00000002
+#define FILE_DEVICE_CD_ROM_FILE_SYSTEM  0x00000003
+#define FILE_DEVICE_CONTROLLER          0x00000004
+#define FILE_DEVICE_DATALINK            0x00000005
+#define FILE_DEVICE_DFS                 0x00000006
+#define FILE_DEVICE_DISK                0x00000007
+#define FILE_DEVICE_DISK_FILE_SYSTEM    0x00000008
+#define FILE_DEVICE_FILE_SYSTEM         0x00000009
+#define FILE_DEVICE_INPORT_PORT         0x0000000a
+#define FILE_DEVICE_KEYBOARD            0x0000000b
+#define FILE_DEVICE_MAILSLOT            0x0000000c
+#define FILE_DEVICE_MIDI_IN             0x0000000d
+#define FILE_DEVICE_MIDI_OUT            0x0000000e
+#define FILE_DEVICE_MOUSE               0x0000000f
+#define FILE_DEVICE_MULTI_UNC_PROVIDER  0x00000010
+#define FILE_DEVICE_NAMED_PIPE          0x00000011
+#define FILE_DEVICE_NETWORK             0x00000012
+#define FILE_DEVICE_NETWORK_BROWSER     0x00000013
+#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
+#define FILE_DEVICE_NULL                0x00000015
+#define FILE_DEVICE_PARALLEL_PORT       0x00000016
+#define FILE_DEVICE_PHYSICAL_NETCARD    0x00000017
+#define FILE_DEVICE_PRINTER             0x00000018
+#define FILE_DEVICE_SCANNER             0x00000019
+#define FILE_DEVICE_SERIAL_MOUSE_PORT   0x0000001a
+#define FILE_DEVICE_SERIAL_PORT         0x0000001b
+#define FILE_DEVICE_SCREEN              0x0000001c
+#define FILE_DEVICE_SOUND               0x0000001d
+#define FILE_DEVICE_STREAMS             0x0000001e
+#define FILE_DEVICE_TAPE                0x0000001f
+#define FILE_DEVICE_TAPE_FILE_SYSTEM    0x00000020
+#define FILE_DEVICE_TRANSPORT           0x00000021
+#define FILE_DEVICE_UNKNOWN             0x00000022
+#define FILE_DEVICE_VIDEO               0x00000023
+#define FILE_DEVICE_VIRTUAL_DISK        0x00000024
+#define FILE_DEVICE_WAVE_IN             0x00000025
+#define FILE_DEVICE_WAVE_OUT            0x00000026
+#define FILE_DEVICE_8042_PORT           0x00000027
+#define FILE_DEVICE_NETWORK_REDIRECTOR  0x00000028
+#define FILE_DEVICE_BATTERY             0x00000029
+#define FILE_DEVICE_BUS_EXTENDER        0x0000002a
+#define FILE_DEVICE_MODEM               0x0000002b
+#define FILE_DEVICE_VDM         0x0000002c
+//
+// Macro definition for defining IOCTL and FSCTL function control codes.  Note
+// that function codes 0-2047 are reserved for Microsoft Corporation, and
+// 2048-4095 are reserved for customers.
+//
+
+#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
+    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
+)
+
+//
+// Define the method codes for how buffers are passed for I/O and FS controls
+//
+
+#define METHOD_BUFFERED                 0
+#define METHOD_IN_DIRECT                1
+#define METHOD_OUT_DIRECT               2
+#define METHOD_NEITHER                  3
+
+//
+// Define the access check value for any access
+//
+//
+// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
+// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
+// constants *MUST* always be in sync.
+//
+
+
+#define FILE_ANY_ACCESS                 0
+#define FILE_READ_ACCESS          ( 0x0001 )    // file & pipe
+#define FILE_WRITE_ACCESS         ( 0x0002 )    // file & pipe
+
+
+// begin_winnt
+
+//
+// Define access rights to files and directories
+//
+
+//
+// The FILE_READ_DATA and FILE_WRITE_DATA constants are also defined in
+// devioctl.h as FILE_READ_ACCESS and FILE_WRITE_ACCESS. The values for these
+// constants *MUST* always be in sync.
+// The values are redefined in devioctl.h because they must be available to
+// both DOS and NT.
+//
+
+#define FILE_READ_DATA            ( 0x0001 )    // file & pipe
+#define FILE_LIST_DIRECTORY       ( 0x0001 )    // directory
+
+#define FILE_WRITE_DATA           ( 0x0002 )    // file & pipe
+#define FILE_ADD_FILE             ( 0x0002 )    // directory
+
+#define FILE_APPEND_DATA          ( 0x0004 )    // file
+#define FILE_ADD_SUBDIRECTORY     ( 0x0004 )    // directory
+#define FILE_CREATE_PIPE_INSTANCE ( 0x0004 )    // named pipe
+
+#define FILE_READ_EA              ( 0x0008 )    // file & directory
+
+#define FILE_WRITE_EA             ( 0x0010 )    // file & directory
+
+#define FILE_EXECUTE              ( 0x0020 )    // file
+#define FILE_TRAVERSE             ( 0x0020 )    // directory
+
+#define FILE_DELETE_CHILD         ( 0x0040 )    // directory
+
+#define FILE_READ_ATTRIBUTES      ( 0x0080 )    // all
+
+#define FILE_WRITE_ATTRIBUTES     ( 0x0100 )    // all
+
+#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
+
+#define FILE_GENERIC_READ         (STANDARD_RIGHTS_READ     |\
+                                   FILE_READ_DATA           |\
+                                   FILE_READ_ATTRIBUTES     |\
+                                   FILE_READ_EA             |\
+                                   SYNCHRONIZE)
+
+
+#define FILE_GENERIC_WRITE        (STANDARD_RIGHTS_WRITE    |\
+                                   FILE_WRITE_DATA          |\
+                                   FILE_WRITE_ATTRIBUTES    |\
+                                   FILE_WRITE_EA            |\
+                                   FILE_APPEND_DATA         |\
+                                   SYNCHRONIZE)
+
+
+#define FILE_GENERIC_EXECUTE      (STANDARD_RIGHTS_EXECUTE  |\
+                                   FILE_READ_ATTRIBUTES     |\
+                                   FILE_EXECUTE             |\
+                                   SYNCHRONIZE)
+
+// end_winnt
+
+
+//
+// Define share access rights to files and directories
+//
+
+#define FILE_SHARE_READ                 0x00000001  // winnt
+#define FILE_SHARE_WRITE                0x00000002  // winnt
+#define FILE_SHARE_DELETE               0x00000004  // winnt
+#define FILE_SHARE_VALID_FLAGS          0x00000007
+
+//
+// Define the file attributes values
+//
+// Note:  0x00000008 is reserved for use for the old DOS VOLID (volume ID)
+//        and is therefore not considered valid in NT.
+//
+// Note:  0x00000010 is reserved for use for the old DOS SUBDIRECTORY flag
+//        and is therefore not considered valid in NT.  This flag has
+//        been disassociated with file attributes since the other flags are
+//        protected with READ_ and WRITE_ATTRIBUTES access to the file.
+//
+// Note:  Note also that the order of these flags is set to allow both the
+//        FAT and the Pinball File Systems to directly set the attributes
+//        flags in attributes words without having to pick each flag out
+//        individually.  The order of these flags should not be changed!
+//
+
+#define FILE_ATTRIBUTE_READONLY         0x00000001  // winnt
+#define FILE_ATTRIBUTE_HIDDEN           0x00000002  // winnt
+#define FILE_ATTRIBUTE_SYSTEM           0x00000004  // winnt
+#define FILE_ATTRIBUTE_DIRECTORY        0x00000010  // winnt
+#define FILE_ATTRIBUTE_ARCHIVE          0x00000020  // winnt
+#define FILE_ATTRIBUTE_NORMAL           0x00000080  // winnt
+#define FILE_ATTRIBUTE_TEMPORARY        0x00000100  // winnt
+#define FILE_ATTRIBUTE_RESERVED0        0x00000200
+#define FILE_ATTRIBUTE_RESERVED1        0x00000400
+#define FILE_ATTRIBUTE_COMPRESSED       0x00000800  // winnt
+#define FILE_ATTRIBUTE_OFFLINE          0x00001000  // winnt
+#define FILE_ATTRIBUTE_PROPERTY_SET     0x00002000
+#define FILE_ATTRIBUTE_VALID_FLAGS      0x00003fb7
+#define FILE_ATTRIBUTE_VALID_SET_FLAGS  0x00003fa7
+
+//
+// Define the create disposition values
+//
+
+#define FILE_SUPERSEDE                  0x00000000
+#define FILE_OPEN                       0x00000001
+#define FILE_CREATE                     0x00000002
+#define FILE_OPEN_IF                    0x00000003
+#define FILE_OVERWRITE                  0x00000004
+#define FILE_OVERWRITE_IF               0x00000005
+#define FILE_MAXIMUM_DISPOSITION        0x00000005
+
+
+//
+// Define the create/open option flags
+//
+
+#define FILE_DIRECTORY_FILE                     0x00000001
+#define FILE_WRITE_THROUGH                      0x00000002
+#define FILE_SEQUENTIAL_ONLY                    0x00000004
+#define FILE_NO_INTERMEDIATE_BUFFERING          0x00000008
+
+#define FILE_SYNCHRONOUS_IO_ALERT               0x00000010
+#define FILE_SYNCHRONOUS_IO_NONALERT            0x00000020
+#define FILE_NON_DIRECTORY_FILE                 0x00000040
+#define FILE_CREATE_TREE_CONNECTION             0x00000080
+
+#define FILE_COMPLETE_IF_OPLOCKED               0x00000100
+#define FILE_NO_EA_KNOWLEDGE                    0x00000200
+//UNUSED                                        0x00000400
+#define FILE_RANDOM_ACCESS                      0x00000800
+
+#define FILE_DELETE_ON_CLOSE                    0x00001000
+#define FILE_OPEN_BY_FILE_ID                    0x00002000
+#define FILE_OPEN_FOR_BACKUP_INTENT             0x00004000
+#define FILE_NO_COMPRESSION                     0x00008000
+
+
+#define FILE_RESERVE_OPFILTER                   0x00100000
+#define FILE_TRANSACTED_MODE                    0x00200000
+#define FILE_OPEN_OFFLINE_FILE                  0x00400000
+
+#define FILE_VALID_OPTION_FLAGS                 0x007fffff
+#define FILE_VALID_PIPE_OPTION_FLAGS            0x00000032
+#define FILE_VALID_MAILSLOT_OPTION_FLAGS        0x00000032
+#define FILE_VALID_SET_FLAGS                    0x00000036
+
+//
+// Define the I/O status information return values for NtCreateFile/NtOpenFile
+//
+
+#define FILE_SUPERSEDED                 0x00000000
+#define FILE_OPENED                     0x00000001
+#define FILE_CREATED                    0x00000002
+#define FILE_OVERWRITTEN                0x00000003
+#define FILE_EXISTS                     0x00000004
+#define FILE_DOES_NOT_EXIST             0x00000005
+
+//
+// Define special ByteOffset parameters for read and write operations
+//
+
+#define FILE_WRITE_TO_END_OF_FILE       0xffffffff
+#define FILE_USE_FILE_POINTER_POSITION  0xfffffffe
+
+//
+// Define alignment requirement values
+//
+
+#define FILE_BYTE_ALIGNMENT             0x00000000
+#define FILE_WORD_ALIGNMENT             0x00000001
+#define FILE_LONG_ALIGNMENT             0x00000003
+#define FILE_QUAD_ALIGNMENT             0x00000007
+#define FILE_OCTA_ALIGNMENT             0x0000000f
+#define FILE_32_BYTE_ALIGNMENT          0x0000001f
+#define FILE_64_BYTE_ALIGNMENT          0x0000003f
+#define FILE_128_BYTE_ALIGNMENT         0x0000007f
+#define FILE_256_BYTE_ALIGNMENT         0x000000ff
+#define FILE_512_BYTE_ALIGNMENT         0x000001ff
+
+//
+// Define the maximum length of a filename string
+//
+
+#define MAXIMUM_FILENAME_LENGTH         256
+
+//
+// Define the various device characteristics flags
+//
+
+#define FILE_REMOVABLE_MEDIA            0x00000001
+#define FILE_READ_ONLY_DEVICE           0x00000002
+#define FILE_FLOPPY_DISKETTE            0x00000004
+#define FILE_WRITE_ONCE_MEDIA           0x00000008
+#define FILE_REMOTE_DEVICE              0x00000010
+#define FILE_DEVICE_IS_MOUNTED          0x00000020
+#define FILE_VIRTUAL_VOLUME             0x00000040
+
+#ifndef _FILESYSTEMFSCTL_
+#define _FILESYSTEMFSCTL_
+
+#endif // _FILESYSTEMFSCTL_
+
+//
+// The following is a list of the native file system fsctls followed by
+// additional network file system fsctls.  Some values have been
+// decommissioned.
+//
+
+#define FSCTL_REQUEST_OPLOCK_LEVEL_1    CTL_CODE(FILE_DEVICE_FILE_SYSTEM,  0, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_REQUEST_OPLOCK_LEVEL_2    CTL_CODE(FILE_DEVICE_FILE_SYSTEM,  1, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_REQUEST_BATCH_OPLOCK      CTL_CODE(FILE_DEVICE_FILE_SYSTEM,  2, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_OPLOCK_BREAK_ACKNOWLEDGE  CTL_CODE(FILE_DEVICE_FILE_SYSTEM,  3, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_OPBATCH_ACK_CLOSE_PENDING CTL_CODE(FILE_DEVICE_FILE_SYSTEM,  4, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_OPLOCK_BREAK_NOTIFY       CTL_CODE(FILE_DEVICE_FILE_SYSTEM,  5, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_LOCK_VOLUME               CTL_CODE(FILE_DEVICE_FILE_SYSTEM,  6, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_UNLOCK_VOLUME             CTL_CODE(FILE_DEVICE_FILE_SYSTEM,  7, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_DISMOUNT_VOLUME           CTL_CODE(FILE_DEVICE_FILE_SYSTEM,  8, METHOD_BUFFERED, FILE_ANY_ACCESS)
+// decommissioned fsctl value                                              9
+#define FSCTL_IS_VOLUME_MOUNTED         CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 10, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_IS_PATHNAME_VALID         CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 11, METHOD_BUFFERED, FILE_ANY_ACCESS) // PATHNAME_BUFFER,
+#define FSCTL_MARK_VOLUME_DIRTY         CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
+// decommissioned fsctl value                                             13
+#define FSCTL_QUERY_RETRIEVAL_POINTERS  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 14,  METHOD_NEITHER, FILE_ANY_ACCESS)
+#define FSCTL_GET_COMPRESSION           CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_SET_COMPRESSION           CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 16, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
+// decommissioned fsctl value                                             17
+// decommissioned fsctl value                                             18
+#define FSCTL_MARK_AS_SYSTEM_HIVE       CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 19,  METHOD_NEITHER, FILE_ANY_ACCESS)
+#define FSCTL_OPLOCK_BREAK_ACK_NO_2     CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 20, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_INVALIDATE_VOLUMES        CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 21, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_QUERY_FAT_BPB             CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 22, METHOD_BUFFERED, FILE_ANY_ACCESS) // FSCTL_QUERY_FAT_BPB_BUFFER
+#define FSCTL_REQUEST_FILTER_OPLOCK     CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 23, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_FILESYSTEM_GET_STATISTICS CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 24, METHOD_BUFFERED, FILE_ANY_ACCESS) // FILESYSTEM_STATISTICS
+#if(_WIN32_WINNT >= 0x0400)
+#define FSCTL_GET_NTFS_VOLUME_DATA      CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 25, METHOD_BUFFERED, FILE_ANY_ACCESS) // NTFS_VOLUME_DATA_BUFFER
+#define FSCTL_GET_NTFS_FILE_RECORD      CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 26, METHOD_BUFFERED, FILE_ANY_ACCESS) // NTFS_FILE_RECORD_INPUT_BUFFER, NTFS_FILE_RECORD_OUTPUT_BUFFER
+#define FSCTL_GET_VOLUME_BITMAP         CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 27,  METHOD_NEITHER, FILE_ANY_ACCESS) // STARTING_LCN_INPUT_BUFFER, VOLUME_BITMAP_BUFFER
+#define FSCTL_GET_RETRIEVAL_POINTERS    CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 28,  METHOD_NEITHER, FILE_ANY_ACCESS) // STARTING_VCN_INPUT_BUFFER, RETRIEVAL_POINTERS_BUFFER
+#define FSCTL_MOVE_FILE                 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 29, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // MOVE_FILE_DATA,
+#define FSCTL_IS_VOLUME_DIRTY           CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 30, METHOD_BUFFERED, FILE_ANY_ACCESS)
+// decomissioned fsctl value                                              31
+#define FSCTL_ALLOW_EXTENDED_DASD_IO    CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 32, METHOD_NEITHER,  FILE_ANY_ACCESS)
+#endif /* _WIN32_WINNT >= 0x0400 */
+
+//
+// Define the base asynchronous I/O argument types
+//
+
+typedef struct _IO_STATUS_BLOCK {
+    NTSTATUS Status;
+    ULONG Information;
+} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
+
+//
+// Define an Asynchronous Procedure Call from I/O viewpoint
+//
+
+typedef
+VOID
+(*PIO_APC_ROUTINE) (
+    IN PVOID ApcContext,
+    IN PIO_STATUS_BLOCK IoStatusBlock,
+    IN ULONG Reserved
+    );
+
+//
+// Define the file information class values
+//
+// WARNING:  The order of the following values are assumed by the I/O system.
+//           Any changes made here should be reflected there as well.
+//
+
+typedef enum _FILE_INFORMATION_CLASS {
+    FileDirectoryInformation = 1,
+    FileFullDirectoryInformation,
+    FileBothDirectoryInformation,
+    FileBasicInformation,
+    FileStandardInformation,
+    FileInternalInformation,
+    FileEaInformation,
+    FileAccessInformation,
+    FileNameInformation,
+    FileRenameInformation,
+    FileLinkInformation,
+    FileNamesInformation,
+    FileDispositionInformation,
+    FilePositionInformation,
+    FileFullEaInformation,
+    FileModeInformation,
+    FileAlignmentInformation,
+    FileAllInformation,
+    FileAllocationInformation,
+    FileEndOfFileInformation,
+    FileAlternateNameInformation,
+    FileStreamInformation,
+    FilePipeInformation,
+    FilePipeLocalInformation,
+    FilePipeRemoteInformation,
+    FileMailslotQueryInformation,
+    FileMailslotSetInformation,
+    FileCompressionInformation,
+    FileCopyOnWriteInformation,
+    FileCompletionInformation,
+    FileMoveClusterInformation,
+    FileOleClassIdInformation,
+    FileOleStateBitsInformation,
+    FileNetworkOpenInformation,
+    FileObjectIdInformation,
+    FileOleAllInformation,
+    FileOleDirectoryInformation,
+    FileContentIndexInformation,
+    FileInheritContentIndexInformation,
+    FileOleInformation,
+    FileMaximumInformation
+} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
+
+//
+// Define the various structures which are returned on query operations
+//
+
+typedef struct _FILE_BASIC_INFORMATION {                    
+    LARGE_INTEGER CreationTime;                             
+    LARGE_INTEGER LastAccessTime;                           
+    LARGE_INTEGER LastWriteTime;                            
+    LARGE_INTEGER ChangeTime;                               
+    ULONG FileAttributes;                                   
+} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;         
+                                                            
+typedef struct _FILE_STANDARD_INFORMATION {                 
+    LARGE_INTEGER AllocationSize;                           
+    LARGE_INTEGER EndOfFile;                                
+    ULONG NumberOfLinks;                                    
+    BOOLEAN DeletePending;                                  
+    BOOLEAN Directory;                                      
+} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;   
+                                                            
+typedef struct _FILE_POSITION_INFORMATION {                 
+    LARGE_INTEGER CurrentByteOffset;                        
+} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;   
+                                                            
+typedef struct _FILE_ALIGNMENT_INFORMATION {                
+    ULONG AlignmentRequirement;                             
+} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; 
+                                                            
+typedef struct _FILE_NETWORK_OPEN_INFORMATION {                 
+    LARGE_INTEGER CreationTime;                                 
+    LARGE_INTEGER LastAccessTime;                               
+    LARGE_INTEGER LastWriteTime;                                
+    LARGE_INTEGER ChangeTime;                                   
+    LARGE_INTEGER AllocationSize;                               
+    LARGE_INTEGER EndOfFile;                                    
+    ULONG FileAttributes;                                       
+} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;   
+                                                                
+typedef struct _FILE_DISPOSITION_INFORMATION {                  
+    BOOLEAN DeleteFile;                                         
+} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; 
+                                                                
+typedef struct _FILE_END_OF_FILE_INFORMATION {                  
+    LARGE_INTEGER EndOfFile;                                    
+} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; 
+                                                                
+
+typedef struct _FILE_FULL_EA_INFORMATION {
+    ULONG NextEntryOffset;
+    UCHAR Flags;
+    UCHAR EaNameLength;
+    USHORT EaValueLength;
+    CHAR EaName[1];
+} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
+
+//
+// Define the file system information class values
+//
+// WARNING:  The order of the following values are assumed by the I/O system.
+//           Any changes made here should be reflected there as well.
+
+typedef enum _FSINFOCLASS {
+    FileFsVolumeInformation = 1,
+    FileFsLabelInformation,
+    FileFsSizeInformation,
+    FileFsDeviceInformation,
+    FileFsAttributeInformation,
+    FileFsControlInformation,
+    FileFsQuotaQueryInformation,        // temporary
+    FileFsQuotaSetInformation,          // temporary
+    FileFsMaximumInformation
+} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
+
+typedef struct _FILE_FS_DEVICE_INFORMATION {                    
+    DEVICE_TYPE DeviceType;                                     
+    ULONG Characteristics;                                      
+} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;     
+
+//
+// Registry Specific Access Rights.
+//
+
+#define KEY_QUERY_VALUE         (0x0001)
+#define KEY_SET_VALUE           (0x0002)
+#define KEY_CREATE_SUB_KEY      (0x0004)
+#define KEY_ENUMERATE_SUB_KEYS  (0x0008)
+#define KEY_NOTIFY              (0x0010)
+#define KEY_CREATE_LINK         (0x0020)
+
+#define KEY_READ                ((STANDARD_RIGHTS_READ       |\
+                                  KEY_QUERY_VALUE            |\
+                                  KEY_ENUMERATE_SUB_KEYS     |\
+                                  KEY_NOTIFY)                 \
+                                  &                           \
+                                 (~SYNCHRONIZE))
+
+
+#define KEY_WRITE               ((STANDARD_RIGHTS_WRITE      |\
+                                  KEY_SET_VALUE              |\
+                                  KEY_CREATE_SUB_KEY)         \
+                                  &                           \
+                                 (~SYNCHRONIZE))
+
+#define KEY_EXECUTE             ((KEY_READ)                   \
+                                  &                           \
+                                 (~SYNCHRONIZE))
+
+#define KEY_ALL_ACCESS          ((STANDARD_RIGHTS_ALL        |\
+                                  KEY_QUERY_VALUE            |\
+                                  KEY_SET_VALUE              |\
+                                  KEY_CREATE_SUB_KEY         |\
+                                  KEY_ENUMERATE_SUB_KEYS     |\
+                                  KEY_NOTIFY                 |\
+                                  KEY_CREATE_LINK)            \
+                                  &                           \
+                                 (~SYNCHRONIZE))
+
+//
+// Open/Create Options
+//
+
+#define REG_OPTION_RESERVED         (0x00000000L)   // Parameter is reserved
+
+#define REG_OPTION_NON_VOLATILE     (0x00000000L)   // Key is preserved
+                                                    // when system is rebooted
+
+#define REG_OPTION_VOLATILE         (0x00000001L)   // Key is not preserved
+                                                    // when system is rebooted
+
+#define REG_OPTION_CREATE_LINK      (0x00000002L)   // Created key is a
+                                                    // symbolic link
+
+#define REG_OPTION_BACKUP_RESTORE   (0x00000004L)   // open for backup or restore
+                                                    // special access rules
+                                                    // privilege required
+
+#define REG_OPTION_OPEN_LINK        (0x00000008L)   // Open symbolic link
+
+#define REG_LEGAL_OPTION            \
+                (REG_OPTION_RESERVED            |\
+                 REG_OPTION_NON_VOLATILE        |\
+                 REG_OPTION_VOLATILE            |\
+                 REG_OPTION_CREATE_LINK         |\
+                 REG_OPTION_BACKUP_RESTORE      |\
+                 REG_OPTION_OPEN_LINK)
+
+//
+// Key creation/open disposition
+//
+
+#define REG_CREATED_NEW_KEY         (0x00000001L)   // New Registry Key created
+#define REG_OPENED_EXISTING_KEY     (0x00000002L)   // Existing Key opened
+
+//
+// Key restore flags
+//
+
+#define REG_WHOLE_HIVE_VOLATILE     (0x00000001L)   // Restore whole hive volatile
+#define REG_REFRESH_HIVE            (0x00000002L)   // Unwind changes to last flush
+#define REG_NO_LAZY_FLUSH           (0x00000004L)   // Never lazy flush this hive
+
+//
+// Key query structures
+//
+
+typedef struct _KEY_BASIC_INFORMATION {
+    LARGE_INTEGER LastWriteTime;
+    ULONG   TitleIndex;
+    ULONG   NameLength;
+    WCHAR   Name[1];            // Variable length string
+} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;
+
+typedef struct _KEY_NODE_INFORMATION {
+    LARGE_INTEGER LastWriteTime;
+    ULONG   TitleIndex;
+    ULONG   ClassOffset;
+    ULONG   ClassLength;
+    ULONG   NameLength;
+    WCHAR   Name[1];            // Variable length string
+//          Class[1];           // Variable length string not declared
+} KEY_NODE_INFORMATION, *PKEY_NODE_INFORMATION;
+
+typedef struct _KEY_FULL_INFORMATION {
+    LARGE_INTEGER LastWriteTime;
+    ULONG   TitleIndex;
+    ULONG   ClassOffset;
+    ULONG   ClassLength;
+    ULONG   SubKeys;
+    ULONG   MaxNameLen;
+    ULONG   MaxClassLen;
+    ULONG   Values;
+    ULONG   MaxValueNameLen;
+    ULONG   MaxValueDataLen;
+    WCHAR   Class[1];           // Variable length
+} KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION;
+
+typedef enum _KEY_INFORMATION_CLASS {
+    KeyBasicInformation,
+    KeyNodeInformation,
+    KeyFullInformation
+} KEY_INFORMATION_CLASS;
+
+typedef struct _KEY_WRITE_TIME_INFORMATION {
+    LARGE_INTEGER LastWriteTime;
+} KEY_WRITE_TIME_INFORMATION, *PKEY_WRITE_TIME_INFORMATION;
+
+typedef enum _KEY_SET_INFORMATION_CLASS {
+    KeyWriteTimeInformation
+} KEY_SET_INFORMATION_CLASS;
+
+//
+// Value entry query structures
+//
+
+typedef struct _KEY_VALUE_BASIC_INFORMATION {
+    ULONG   TitleIndex;
+    ULONG   Type;
+    ULONG   NameLength;
+    WCHAR   Name[1];            // Variable size
+} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;
+
+typedef struct _KEY_VALUE_FULL_INFORMATION {
+    ULONG   TitleIndex;
+    ULONG   Type;
+    ULONG   DataOffset;
+    ULONG   DataLength;
+    ULONG   NameLength;
+    WCHAR   Name[1];            // Variable size
+//          Data[1];            // Variable size data not declared
+} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
+
+typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
+    ULONG   TitleIndex;
+    ULONG   Type;
+    ULONG   DataLength;
+    UCHAR   Data[1];            // Variable size
+} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
+
+typedef struct _KEY_VALUE_ENTRY {
+    PUNICODE_STRING ValueName;
+    ULONG           DataLength;
+    ULONG           DataOffset;
+    ULONG           Type;
+} KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY;
+
+typedef enum _KEY_VALUE_INFORMATION_CLASS {
+    KeyValueBasicInformation,
+    KeyValueFullInformation,
+    KeyValuePartialInformation
+} KEY_VALUE_INFORMATION_CLASS;
+
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+NtEnumerateKey(
+    IN HANDLE KeyHandle,
+    IN ULONG Index,
+    IN KEY_INFORMATION_CLASS KeyInformationClass,
+    IN PVOID KeyInformation,
+    IN ULONG Length,
+    IN PULONG ResultLength
+    );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+NtOpenKey(
+    OUT PHANDLE KeyHandle,
+    IN ACCESS_MASK DesiredAccess,
+    IN POBJECT_ATTRIBUTES ObjectAttributes
+    );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+NtQueryValueKey(
+    IN HANDLE KeyHandle,
+    IN PUNICODE_STRING ValueName,
+    IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
+    IN PVOID KeyValueInformation,
+    IN ULONG Length,
+    IN PULONG ResultLength
+    );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+NtSetValueKey(
+    IN HANDLE KeyHandle,
+    IN PUNICODE_STRING ValueName,
+    IN ULONG TitleIndex OPTIONAL,
+    IN ULONG Type,
+    IN PVOID Data,
+    IN ULONG DataSize
+    );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+NtDeleteValueKey(
+    IN HANDLE KeyHandle,
+    IN PUNICODE_STRING ValueName
+    );
+
+
+#define OBJ_NAME_PATH_SEPARATOR ((WCHAR)L'\\')
+
+//
+// Object Manager Object Type Specific Access Rights.
+//
+
+#define OBJECT_TYPE_CREATE (0x0001)
+
+#define OBJECT_TYPE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)
+
+//
+// Object Manager Directory Specific Access Rights.
+//
+
+#define DIRECTORY_QUERY                 (0x0001)
+#define DIRECTORY_TRAVERSE              (0x0002)
+#define DIRECTORY_CREATE_OBJECT         (0x0004)
+#define DIRECTORY_CREATE_SUBDIRECTORY   (0x0008)
+
+#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
+
+//
+// Object Manager Symbolic Link Specific Access Rights.
+//
+
+#define SYMBOLIC_LINK_QUERY (0x0001)
+
+#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)
+
+typedef struct _OBJECT_NAME_INFORMATION {               
+    UNICODE_STRING Name;                                
+} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;   
+
+//
+// Section Information Structures.
+//
+
+typedef enum _SECTION_INHERIT {
+    ViewShare = 1,
+    ViewUnmap = 2
+} SECTION_INHERIT;
+
+//
+// Section Access Rights.
+//
+
+// begin_winnt
+#define SECTION_QUERY       0x0001
+#define SECTION_MAP_WRITE   0x0002
+#define SECTION_MAP_READ    0x0004
+#define SECTION_MAP_EXECUTE 0x0008
+#define SECTION_EXTEND_SIZE 0x0010
+
+#define SECTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY|\
+                            SECTION_MAP_WRITE |      \
+                            SECTION_MAP_READ |       \
+                            SECTION_MAP_EXECUTE |    \
+                            SECTION_EXTEND_SIZE)
+// end_winnt
+
+#define SEGMENT_ALL_ACCESS SECTION_ALL_ACCESS
+
+#define PAGE_NOACCESS          0x01     // winnt
+#define PAGE_READONLY          0x02     // winnt
+#define PAGE_READWRITE         0x04     // winnt
+#define PAGE_WRITECOPY         0x08     // winnt
+#define PAGE_EXECUTE           0x10     // winnt
+#define PAGE_EXECUTE_READ      0x20     // winnt
+#define PAGE_EXECUTE_READWRITE 0x40     // winnt
+#define PAGE_EXECUTE_WRITECOPY 0x80     // winnt
+#define PAGE_GUARD            0x100     // winnt
+#define PAGE_NOCACHE          0x200     // winnt
+
+#define MEM_COMMIT           0x1000     
+#define MEM_RESERVE          0x2000     
+#define MEM_DECOMMIT         0x4000     
+#define MEM_RELEASE          0x8000     
+#define MEM_FREE            0x10000     
+#define MEM_PRIVATE         0x20000     
+#define MEM_MAPPED          0x40000     
+#define MEM_RESET           0x80000     
+#define MEM_TOP_DOWN       0x100000     
+#define MEM_LARGE_PAGES  0x20000000     
+#define SEC_RESERVE       0x4000000     
+#define PROCESS_ALL_ACCESS        (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
+                                   0xFFF)
+
+
+#define MAXIMUM_PROCESSORS 32
+
+// end_winnt
+
+//
+// Thread Specific Access Rights
+//
+
+#define THREAD_TERMINATE               (0x0001)  // winnt
+#define THREAD_SET_INFORMATION         (0x0020)  // winnt
+
+#define THREAD_ALL_ACCESS         (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
+                                   0x3FF)
+
+//
+// ClientId
+//
+
+typedef struct _CLIENT_ID {
+    HANDLE UniqueProcess;
+    HANDLE UniqueThread;
+} CLIENT_ID;
+typedef CLIENT_ID *PCLIENT_ID;
+
+//
+//  Define the size of the 80387 save area, which is in the context frame.
+//
+
+#define SIZE_OF_80387_REGISTERS      80
+
+//
+// The following flags control the contents of the CONTEXT structure.
+//
+
+#if !defined(RC_INVOKED)
+
+#define CONTEXT_i386    0x00010000    // this assumes that i386 and
+#define CONTEXT_i486    0x00010000    // i486 have identical context records
+
+// end_wx86
+
+#define CONTEXT_CONTROL         (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP
+#define CONTEXT_INTEGER         (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI
+#define CONTEXT_SEGMENTS        (CONTEXT_i386 | 0x00000004L) // DS, ES, FS, GS
+#define CONTEXT_FLOATING_POINT  (CONTEXT_i386 | 0x00000008L) // 387 state
+#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L) // DB 0-3,6,7
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER |\
+                      CONTEXT_SEGMENTS)
+
+// begin_wx86
+
+#endif
+
+typedef struct _FLOATING_SAVE_AREA {
+    ULONG   ControlWord;
+    ULONG   StatusWord;
+    ULONG   TagWord;
+    ULONG   ErrorOffset;
+    ULONG   ErrorSelector;
+    ULONG   DataOffset;
+    ULONG   DataSelector;
+    UCHAR   RegisterArea[SIZE_OF_80387_REGISTERS];
+    ULONG   Cr0NpxState;
+} FLOATING_SAVE_AREA;
+
+typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA;
+
+//
+// Context Frame
+//
+//  This frame has a several purposes: 1) it is used as an argument to
+//  NtContinue, 2) is is used to constuct a call frame for APC delivery,
+//  and 3) it is used in the user level thread creation routines.
+//
+//  The layout of the record conforms to a standard call frame.
+//
+
+typedef struct _CONTEXT {
+
+    //
+    // The flags values within this flag control the contents of
+    // a CONTEXT record.
+    //
+    // If the context record is used as an&nbs