實現功能:
將用戶指定的某個文件A 虛擬成一個分區B, 用戶在分區上B操作的數據會保存到文件A上
需要解決的問題:
1、如何虛擬出一個新的設備(分區)?
2、如何將訪問這個分區的操作轉化為讀取某個文件的操作?
2008.09.02
2008.09.03
extern "C" void
TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo)


{

WCHAR tmp[3] =
{0, ':', 0};
int j = nDriveNo + (WCHAR) 'A';
tmp[0] = (short) j;
wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX);
KdPrint(("TCGetNTNameFromNumber: Create Driver ntname = \"%d\"\n", nDriveNo));
KdPrint(("TCGetNTNameFromNumber: Create Driver ntname = \"%s\"\n", ntname));
wcsncat (ntname, tmp, 1);
KdPrint(("TCGetNTNameFromNumber: Create Driver ntname = \"%s\"\n", ntname));
}

extern "C" NTSTATUS
DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)


{
NTSTATUS ntStatus;
WCHAR dosname[32], ntname[32];
ULONG devChars = 0;

// 定義一個 Unicode 字符串
UNICODE_STRING ntUnicodeString;
//RtlInitUnicodeString(&nameString, L"\\FileSystem\\Filters\\SFilter");

DriverObject->DriverExtension->AddDevice = AddDevice;

KdPrint(("SFilter!DriverEntry\n"));

TCGetNTNameFromNumber (ntname, 3);
KdPrint(("SFilter!DriverEntry: Create Driver ntname = \"%s\"\n", &ntname));
RtlInitUnicodeString (&ntUnicodeString, ntname);

KdPrint(("SFilter!DriverEntry: Create Driver ntUnicodeString = \"%s\"\n", &ntUnicodeString));

輸出結果如下:
SFilter!DriverEntry
TCGetNTNameFromNumber: Create Driver ntname = "3"
TCGetNTNameFromNumber: Create Driver ntname = "\Device\TrueCryptVolume"
TCGetNTNameFromNumber: Create Driver ntname = "\Device\TrueCryptVolume"
SFilter!DriverEntry: Create Driver ntname = "\Device\TrueCryptVolume"
SFilter!DriverEntry: Create Driver ntUnicodeString = "H"
SFilter!DriverEntry: Error Creating Control Device Object "?", status=c000003b
接著,藍屏……
表示很懷疑,把 tmp 的值也打印出來
KdPrint(("TCGetNTNameFromNumber: Create Driver tmp = \"%s\"\n", tmp));
wcsncat (ntname, tmp, 1);
----------------------------------------------------------------------------------------
結果顯示
SFilter!DriverEntry
TCGetNTNameFromNumber: Create Driver ntname = "3"
TCGetNTNameFromNumber: Create Driver ntname = "\Device\TrueCryptVolume"
TCGetNTNameFromNumber: Create Driver tmp = "D"
TCGetNTNameFromNumber: Create Driver ntname = "\Device\TrueCryptVolume"
SFilter!DriverEntry: Create Driver ntname = "\Device\TrueCryptVolume"
SFilter!DriverEntry: Create Driver ntUnicodeString = "H"
SFilter!DriverEntry: Error Creating Control Device Object "?", status=c000003b
---
根據代碼的執行結果:
tmp 的值應該是 D: 才對!!!!! 奇怪!!!
問題,
1、KdPrint 在打印 WCHAR[] 與 UNICODE_STRING 時的處理
2、WCHAR[] 與 UNICODE_STRING 的連接又該如何?(如果沒有成功編譯 TrueCrypt,所以無法跟蹤到它里面的值的變化)
--------------------------------------------------------
于是先把創建設備的代碼去掉,先把 ntUnicodeString 正確顯示出來
#ifdef __cplusplus
extern "C"


{
#endif
#include <ntddk.h>
#ifdef __cplusplus
}
#endif
#ifdef NT4_DRIVER
#define DRIVER_STR WIDE
#else
#define DRIVER_STR
#endif
#define NT_MOUNT_PREFIX DRIVER_STR("\\Device\\TrueCryptVolume")
PDEVICE_OBJECT gSFilterDriverObject = NULL;

/**//* This structure is allocated for non-root devices! WARNING: bRootDevice
must be the first member of the structure! */
typedef struct EXTENSION


{
} EXTENSION, *PEXTENSION;
typedef struct _DEVICE_EXTENSION


{
PDEVICE_OBJECT fdo;
PDEVICE_OBJECT NextStackDevice;
UNICODE_STRING ifSymLinkName;
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
extern "C" NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject)


{
NTSTATUS status;
PDEVICE_OBJECT fdo;
status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_DISK,
0,
FALSE,
&fdo);
if( !NT_SUCCESS(status))
return status;
PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
dx->fdo = fdo;
dx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
}
extern "C" void
TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo)


{

WCHAR tmp[3] =
{0, ':', 0};
int j = nDriveNo + (WCHAR) 'A';
tmp[0] = (short) j;
wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX);
KdPrint(("TCGetNTNameFromNumber: Create Driver ntname = \"%d\"\n", nDriveNo));
KdPrint(("TCGetNTNameFromNumber: Create Driver ntname = \"%s\"\n", ntname));
KdPrint(("TCGetNTNameFromNumber: Create Driver tmp = \"%s\"\n", tmp));
wcsncat (ntname, tmp, 1);
KdPrint(("TCGetNTNameFromNumber: Create Driver ntname = \"%s\"\n", ntname));
}
extern "C" NTSTATUS
DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)


{
NTSTATUS ntStatus = STATUS_SUCCESS;
WCHAR dosname[32], ntname[32];
ULONG devChars = 0;
// 定義一個 Unicode 字符串
UNICODE_STRING ntUnicodeString;
//RtlInitUnicodeString(&nameString, L"\\FileSystem\\Filters\\SFilter");
DriverObject->DriverExtension->AddDevice = AddDevice;
KdPrint(("SFilter!DriverEntry\n"));
TCGetNTNameFromNumber (ntname, 3);
KdPrint(("SFilter!DriverEntry: Create Driver ntname = \"%s\"\n", &ntname));
RtlInitUnicodeString (&ntUnicodeString, ntname);
KdPrint(("SFilter!DriverEntry: Create Driver ntUnicodeString = \"%s\"\n", &ntUnicodeString));

/**//*
devChars = FILE_DEVICE_SECURE_OPEN;
PDEVICE_OBJECT pDeviceObject = NULL;
// 創建虛擬設備
ntStatus = IoCreateDevice (
DriverObject, /* Our Driver Object * /
sizeof (EXTENSION), /* Size of state information * /
&ntUnicodeString, /* Device name "\Device\Name" * /
FILE_DEVICE_DISK, /* Device type * /
devChars, /* Device characteristics * /
FALSE, /* Exclusive device * /
&pDeviceObject); /* Returned ptr to Device Object * /
if ( !NT_SUCCESS( ntStatus ) )
{
KdPrint(("SFilter!DriverEntry: Error Creating Control Device Object \"%wZ\", status=%08x\n", &ntUnicodeString, ntStatus));
}
else
{
KdPrint(("SFilter!DriverEntry: Success Creating Control Device Object \"%wZ\", status=%08x\n", &ntUnicodeString, ntStatus));
}*/
return ntStatus;
}

---
代碼改成了這樣后, 調試依然會藍屏。

SFilter!DriverEntry
TCGetNTNameFromNumber: Create Driver ntname = "3"
TCGetNTNameFromNumber: Create Driver ntname = "\Device\TrueCryptVolume"
TCGetNTNameFromNumber: Create Driver tmp = "D"
TCGetNTNameFromNumber: Create Driver ntname = "\Device\TrueCryptVolume"
SFilter!DriverEntry: Create Driver ntname = "\Device\TrueCryptVolume"
SFilter!DriverEntry: Create Driver ntUnicodeString = "H"

*** Fatal System Error: 0x0000007e
(0xC0000005,0x46656D61,0xF9EA2770,0xF9EA246C)

Break instruction exception - code 80000003 (first chance)

A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.

A fatal system error has occurred.



需要回滾代碼。明天再繼續。

2008.09.04
問題1:
運行 TrueCrypt\Driver\BuildDriver.cmd ,不能編譯驅動,提示 "BuildDriver.cmd: error: Cannot copy target."
沒有時間看 ReadMe. 未解決
問題2:
將 TrueCrypt.sln 用工具轉換為 TrueCrypt.dsw ,打開后無論編譯哪一個工程,都會提示很多錯誤信息
未解決
問題3:
IoCreateDevice 最后一個參數 Returned ptr to Device Object, 是否需要為其分配空間
-- Answered by bill Bill Gates : Device Object對象由系統分配,系統會在這個對象reference count為0的時候自動銷毀。
安裝 filedisk 后
產生問題1: 看了下設備管理器并沒有多出一個設備,那么E盤怎么出來的?
用 WinObj.exe 也無所發現 (先迷茫一下先!!!)
產生問題1:
filedisk 的 exe 為何不能用 nmake 來編譯?
產生問題2:
ddk 也可以用來編譯 exe 程序?
產生問題3:
如果用 vc 建一個 Win32 Console Application 工程又能否編譯?
-- 試了一下,果然是可以滴!!
產生很奇怪的問題1:
用自己編譯的 exe && sys 運后,可以正常虛擬一個分區出來,但 win 提示不能格式化分區
-- 用原先的 exe 再試一下, 試過后, win 仍然提示不能格式化分區
于是用回 原先的 sys 再試一下,
突然間懷疑,是不是 映象文件的問題,因為我用的是
filedisk /mount 0 c:\test.txt 8M e:
后綴名是 .txt
改成 filedisk /mount 0 c:\test.img 8M e: 后 win 提示格式化分區成功,于是
產生很奇怪的問題2:
filedisk 的映象文件的后綴名如果為 .txt ,會導致 win 不能格式化虛擬出來的分區?
按道理應該跟映象文件的后綴名無關才是,估計要研究下里面的代碼才清楚了!!!
-- 未解決
另外還產生很奇怪的問題3:
我把映象文件的大小設置 1K, win會提示“無法完成格式化”,難道 win 需要空間存放文件分配表?
試了一下,映象文件的大小在 3M 左右,win才可以格式化成功,具體值無嘗試

另一方面,如果 windows 的分區在格式化時,它應該會建一個
{文件分配表}之類的東西,

而這個
{文件分配表}的大小應該跟分區的大小有關 (暫無找到相關的資料,未解決)
-- 未解決
將用戶指定的某個文件A 虛擬成一個分區B, 用戶在分區上B操作的數據會保存到文件A上
需要解決的問題:
1、如何虛擬出一個新的設備(分區)?
2、如何將訪問這個分區的操作轉化為讀取某個文件的操作?
2008.09.02
大概看了 TrueCrypt 源代碼
1.
DriverEntry() 中
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
{
DriverObject->MajorFunction[i] = TCDispatchQueueIRP;
}
2、TCDispatchQueueIRP 處理 IRP 代碼
case IRP_MJ_FLUSH_BUFFERS:
case IRP_MJ_READ:
case IRP_MJ_WRITE:
case IRP_MJ_DEVICE_CONTROL:
if (Extension->bRootDevice)
{
if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
return ProcessMainDeviceControlIrp (DeviceObject, Extension, Irp);
break;
}
在處理IRP時,還需要注意區分是系統真實分區發出的IRP,還是由虛擬出來的分區發出的IRP
3、ProcessMainDeviceControlIrp() 中
case TC_IOCTL_MOUNT_VOLUME:
Irp->IoStatus.Information = sizeof (MOUNT_STRUCT);
Irp->IoStatus.Status = MountDevice (DeviceObject, mount);
DriverMutexRelease ();
判斷由應用程序發出的 CTL_CODE
4、MountDevice() 中
ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject,
mount);
if (!NT_SUCCESS (ntStatus))
{
Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus);
return ntStatus;
}
5、TCCreateDeviceObject() 中
NTSTATUS
TCCreateDeviceObject (PDRIVER_OBJECT DriverObject,
PDEVICE_OBJECT * ppDeviceObject,
MOUNT_STRUCT * mount)
{
UNICODE_STRING Win32NameString, ntUnicodeString;
WCHAR dosname[32], ntname[32];
PEXTENSION Extension;
NTSTATUS ntStatus;
ULONG devChars = 0;
Dump ("TCCreateDeviceObject BEGIN\n");
ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
TCGetDosNameFromNumber (dosname, mount->nDosDriveNo);
TCGetNTNameFromNumber (ntname, mount->nDosDriveNo);
RtlInitUnicodeString (&ntUnicodeString, ntname);
RtlInitUnicodeString (&Win32NameString, dosname);
devChars = FILE_DEVICE_SECURE_OPEN;
devChars |= mount->bMountReadOnly ? FILE_READ_ONLY_DEVICE : 0;
devChars |= mount->bMountRemovable ? FILE_REMOVABLE_MEDIA : 0;
Dump ("Creating device nt=%ls dos=%ls\n", ntname, dosname);
ntStatus = IoCreateDevice (
DriverObject, /* Our Driver Object */
sizeof (EXTENSION), /* Size of state information */
&ntUnicodeString, /* Device name "\Device\Name" */
FILE_DEVICE_DISK, /* Device type */
devChars, /* Device characteristics */
FALSE, /* Exclusive device */
ppDeviceObject); /* Returned ptr to Device Object */
if (!NT_SUCCESS (ntStatus))
{
Dump ("TCCreateDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
return ntStatus;/* Failed to create DeviceObject */
}
/* Initialize device object and extension. */
(*ppDeviceObject)->Flags |= DO_DIRECT_IO;
(*ppDeviceObject)->StackSize += 2; // Reduce occurrence of NO_MORE_IRP_STACK_LOCATIONS bug check caused by buggy drivers
/* Setup the device extension */
Extension = (PEXTENSION) (*ppDeviceObject)->DeviceExtension;
memset (Extension, 0, sizeof (EXTENSION));
Extension->IsVolumeDevice = TRUE;
Extension->lMagicNumber = 0xabfeacde;
Extension->nDosDriveNo = mount->nDosDriveNo;
Extension->bRemovable = mount->bMountRemovable;
KeInitializeEvent (&Extension->keCreateEvent, SynchronizationEvent, FALSE);
KeInitializeSemaphore (&Extension->RequestSemaphore, 0L, MAXLONG);
KeInitializeSpinLock (&Extension->ListSpinLock);
InitializeListHead (&Extension->ListEntry);
Dump ("TCCreateDeviceObject STATUS_SUCCESS END\n");
return STATUS_SUCCESS;
}
虛擬出一個分區的關鍵應該在 (5) 中,等明天再試。
1.
DriverEntry() 中
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
{
DriverObject->MajorFunction[i] = TCDispatchQueueIRP;
}
2、TCDispatchQueueIRP 處理 IRP 代碼
case IRP_MJ_FLUSH_BUFFERS:
case IRP_MJ_READ:
case IRP_MJ_WRITE:
case IRP_MJ_DEVICE_CONTROL:
if (Extension->bRootDevice)
{
if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
return ProcessMainDeviceControlIrp (DeviceObject, Extension, Irp);
break;
}
在處理IRP時,還需要注意區分是系統真實分區發出的IRP,還是由虛擬出來的分區發出的IRP
3、ProcessMainDeviceControlIrp() 中
case TC_IOCTL_MOUNT_VOLUME:
Irp->IoStatus.Information = sizeof (MOUNT_STRUCT);
Irp->IoStatus.Status = MountDevice (DeviceObject, mount);
DriverMutexRelease ();
判斷由應用程序發出的 CTL_CODE
4、MountDevice() 中
ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject,
mount);
if (!NT_SUCCESS (ntStatus))
{
Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus);
return ntStatus;
}
5、TCCreateDeviceObject() 中
NTSTATUS
TCCreateDeviceObject (PDRIVER_OBJECT DriverObject,
PDEVICE_OBJECT * ppDeviceObject,
MOUNT_STRUCT * mount)
{
UNICODE_STRING Win32NameString, ntUnicodeString;
WCHAR dosname[32], ntname[32];
PEXTENSION Extension;
NTSTATUS ntStatus;
ULONG devChars = 0;
Dump ("TCCreateDeviceObject BEGIN\n");
ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
TCGetDosNameFromNumber (dosname, mount->nDosDriveNo);
TCGetNTNameFromNumber (ntname, mount->nDosDriveNo);
RtlInitUnicodeString (&ntUnicodeString, ntname);
RtlInitUnicodeString (&Win32NameString, dosname);
devChars = FILE_DEVICE_SECURE_OPEN;
devChars |= mount->bMountReadOnly ? FILE_READ_ONLY_DEVICE : 0;
devChars |= mount->bMountRemovable ? FILE_REMOVABLE_MEDIA : 0;
Dump ("Creating device nt=%ls dos=%ls\n", ntname, dosname);
ntStatus = IoCreateDevice (
DriverObject, /* Our Driver Object */
sizeof (EXTENSION), /* Size of state information */
&ntUnicodeString, /* Device name "\Device\Name" */
FILE_DEVICE_DISK, /* Device type */
devChars, /* Device characteristics */
FALSE, /* Exclusive device */
ppDeviceObject); /* Returned ptr to Device Object */
if (!NT_SUCCESS (ntStatus))
{
Dump ("TCCreateDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
return ntStatus;/* Failed to create DeviceObject */
}
/* Initialize device object and extension. */
(*ppDeviceObject)->Flags |= DO_DIRECT_IO;
(*ppDeviceObject)->StackSize += 2; // Reduce occurrence of NO_MORE_IRP_STACK_LOCATIONS bug check caused by buggy drivers
/* Setup the device extension */
Extension = (PEXTENSION) (*ppDeviceObject)->DeviceExtension;
memset (Extension, 0, sizeof (EXTENSION));
Extension->IsVolumeDevice = TRUE;
Extension->lMagicNumber = 0xabfeacde;
Extension->nDosDriveNo = mount->nDosDriveNo;
Extension->bRemovable = mount->bMountRemovable;
KeInitializeEvent (&Extension->keCreateEvent, SynchronizationEvent, FALSE);
KeInitializeSemaphore (&Extension->RequestSemaphore, 0L, MAXLONG);
KeInitializeSpinLock (&Extension->ListSpinLock);
InitializeListHead (&Extension->ListEntry);
Dump ("TCCreateDeviceObject STATUS_SUCCESS END\n");
return STATUS_SUCCESS;
}
虛擬出一個分區的關鍵應該在 (5) 中,等明天再試。
2008.09.03
在昨天的基礎上, 嘗試將創建虛擬設備的部份代碼抽出來
代碼如下:
代碼如下:
1
#ifdef __cplusplus
2
extern "C"
3

{
4
#endif
5
#include <ntddk.h>
6
#ifdef __cplusplus
7
}
8
#endif
9
#ifdef NT4_DRIVER
10
#define DRIVER_STR WIDE
11
#else
12
#define DRIVER_STR
13
#endif
14
#define NT_MOUNT_PREFIX DRIVER_STR("\\Device\\TrueCryptVolume")
15
PDEVICE_OBJECT gSFilterDriverObject = NULL;
16
/**//* This structure is allocated for non-root devices! WARNING: bRootDevice
17
must be the first member of the structure! */
18
typedef struct EXTENSION
19

{
20
} EXTENSION, *PEXTENSION;
21
typedef struct _DEVICE_EXTENSION
22

{
23
PDEVICE_OBJECT fdo;
24
PDEVICE_OBJECT NextStackDevice;
25
UNICODE_STRING ifSymLinkName;
26
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
27
extern "C" NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject,
28
IN PDEVICE_OBJECT PhysicalDeviceObject)
29

{
30
31
NTSTATUS status;
32
PDEVICE_OBJECT fdo;
33
34
status = IoCreateDevice(
35
DriverObject,
36
sizeof(DEVICE_EXTENSION),
37
NULL,
38
FILE_DEVICE_DISK,
39
0,
40
FALSE,
41
&fdo);
42
43
if( !NT_SUCCESS(status))
44
return status;
45
46
PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
47
dx->fdo = fdo;
48
49
dx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
50
fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
51
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
52
53
return STATUS_SUCCESS;
54
}
55
extern "C" void
56
TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo)
57

{
58
WCHAR tmp[3] =
59
{0, ':', 0};
60
int j = nDriveNo + (WCHAR) 'A';
61
tmp[0] = (short) j;
62
wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX);
63
wcsncat (ntname, tmp, 1);
64
}
65
extern "C" NTSTATUS
66
DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
67

{
68
NTSTATUS ntStatus;
69
WCHAR dosname[32], ntname[32];
70
ULONG devChars = 0;
71
// 定義一個 Unicode 字符串
72
UNICODE_STRING ntUnicodeString;
73
//RtlInitUnicodeString(&nameString, L"\\FileSystem\\Filters\\SFilter");
74
DriverObject->DriverExtension->AddDevice = AddDevice;
75
KdPrint(("SFilter!DriverEntry\n"));
76
77
TCGetNTNameFromNumber (ntname, 3);
78
RtlInitUnicodeString (&ntUnicodeString, ntname);
79
KdPrint(("SFilter!DriverEntry: Create Driver \"%wZ\"\n", &ntUnicodeString));
80
devChars = FILE_DEVICE_SECURE_OPEN;
81
82
PDEVICE_OBJECT pDeviceObject = NULL;
83
84
// 創建虛擬設備
85
ntStatus = IoCreateDevice (
86
DriverObject, /**//* Our Driver Object */
87
sizeof (EXTENSION), /**//* Size of state information */
88
&ntUnicodeString, /**//* Device name "\Device\Name" */
89
FILE_DEVICE_DISK, /**//* Device type */
90
devChars, /**//* Device characteristics */
91
FALSE, /**//* Exclusive device */
92
&pDeviceObject); /**//* Returned ptr to Device Object */
93
94
if ( !NT_SUCCESS( ntStatus ) )
95
{
96
KdPrint(("SFilter!DriverEntry: Error Creating Control Device Object \"%wZ\", status=%08x\n", &ntUnicodeString, ntStatus));
97
}
98
else
99
{
100
KdPrint(("SFilter!DriverEntry: Success Creating Control Device Object \"%wZ\", status=%08x\n", &ntUnicodeString, ntStatus));
101
}
102
103
return ntStatus;
104
}
105

2

3



4

5

6

7

8

9

10

11

12

13

14

15

16


17

18

19



20

21

22



23

24

25

26

27

28

29



30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57



58

59



60

61

62

63

64

65

66

67



68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86


87


88


89


90


91


92


93

94

95



96

97

98

99



100

101

102

103

104

105

使用 windgb 調試得到
SFilter!DriverEntry
SFilter!DriverEntry: Create Driver "?"
SFilter!DriverEntry: Error Creating Control Device Object "?", status=c000003b
問題:
設備創建失敗, 可能是由 ntUnicodeString 非法,
但為何 ntUnicodeString 會變成 ?
經試驗, 將 KdPrint 的 \"%wZ\", 改為 %s
KdPrint(("SFilter!DriverEntry\n"));
TCGetNTNameFromNumber (ntname, 3);
KdPrint(("SFilter!DriverEntry: Create Driver ntname = \"%s\"\n", &ntname));
RtlInitUnicodeString (&ntUnicodeString, ntname);
KdPrint(("SFilter!DriverEntry: Create Driver ntUnicodeString = \"%s\"\n", &ntUnicodeString));
--------------------------------------------------
輸出結果
SFilter!DriverEntry: Create Driver ntname = "\Device\TrueCryptVolume"
SFilter!DriverEntry: Create Driver ntUnicodeString = "$"
SFilter!DriverEntry: Error Creating Control Device Object "?", status=c000003b
經過 RtlInitUnicodeString (&ntUnicodeString, ntname); 后
ntUnicodeString 變成了 "?" ?
于是查 MSDN RtlInitUnicodeString 相關的信息, 用法似乎沒有錯
修改了一下程序
SFilter!DriverEntry
SFilter!DriverEntry: Create Driver "?"
SFilter!DriverEntry: Error Creating Control Device Object "?", status=c000003b
問題:
設備創建失敗, 可能是由 ntUnicodeString 非法,
但為何 ntUnicodeString 會變成 ?
經試驗, 將 KdPrint 的 \"%wZ\", 改為 %s
KdPrint(("SFilter!DriverEntry\n"));
TCGetNTNameFromNumber (ntname, 3);
KdPrint(("SFilter!DriverEntry: Create Driver ntname = \"%s\"\n", &ntname));
RtlInitUnicodeString (&ntUnicodeString, ntname);
KdPrint(("SFilter!DriverEntry: Create Driver ntUnicodeString = \"%s\"\n", &ntUnicodeString));
--------------------------------------------------
輸出結果
SFilter!DriverEntry: Create Driver ntname = "\Device\TrueCryptVolume"
SFilter!DriverEntry: Create Driver ntUnicodeString = "$"
SFilter!DriverEntry: Error Creating Control Device Object "?", status=c000003b
經過 RtlInitUnicodeString (&ntUnicodeString, ntname); 后
ntUnicodeString 變成了 "?" ?
于是查 MSDN RtlInitUnicodeString 相關的信息, 用法似乎沒有錯
修改了一下程序
















































輸出結果如下:
SFilter!DriverEntry
TCGetNTNameFromNumber: Create Driver ntname = "3"
TCGetNTNameFromNumber: Create Driver ntname = "\Device\TrueCryptVolume"
TCGetNTNameFromNumber: Create Driver ntname = "\Device\TrueCryptVolume"
SFilter!DriverEntry: Create Driver ntname = "\Device\TrueCryptVolume"
SFilter!DriverEntry: Create Driver ntUnicodeString = "H"
SFilter!DriverEntry: Error Creating Control Device Object "?", status=c000003b
接著,藍屏……
表示很懷疑,把 tmp 的值也打印出來
KdPrint(("TCGetNTNameFromNumber: Create Driver tmp = \"%s\"\n", tmp));
wcsncat (ntname, tmp, 1);
----------------------------------------------------------------------------------------
結果顯示
SFilter!DriverEntry
TCGetNTNameFromNumber: Create Driver ntname = "3"
TCGetNTNameFromNumber: Create Driver ntname = "\Device\TrueCryptVolume"
TCGetNTNameFromNumber: Create Driver tmp = "D"
TCGetNTNameFromNumber: Create Driver ntname = "\Device\TrueCryptVolume"
SFilter!DriverEntry: Create Driver ntname = "\Device\TrueCryptVolume"
SFilter!DriverEntry: Create Driver ntUnicodeString = "H"
SFilter!DriverEntry: Error Creating Control Device Object "?", status=c000003b
---
根據代碼的執行結果:
tmp 的值應該是 D: 才對!!!!! 奇怪!!!
問題,
1、KdPrint 在打印 WCHAR[] 與 UNICODE_STRING 時的處理
2、WCHAR[] 與 UNICODE_STRING 的連接又該如何?(如果沒有成功編譯 TrueCrypt,所以無法跟蹤到它里面的值的變化)
--------------------------------------------------------
于是先把創建設備的代碼去掉,先把 ntUnicodeString 正確顯示出來






























































































































































2008.09.04
今天打算先看下應用層與驅動通信的方法
然后再看下由 Bill Gates 說的(做file disk建議看filedisk的源代碼,在http://www.acc.umu.se/~bosse。)
在開始工作之前,先感謝一下 BillGates ,雖然他已經退休了,但居然光臨我的BLOG,
讀 filedisk 的代碼前,想先使用一下它
看了 Readme,安裝 filedisk 的步驟(它居然連 .inf 都省了,直接用.reg 
暈!!!! )
1、把 filedisk.sys 拷貝到 %systemroot%\system32\drivers\

2、filedisk.reg 里面設置的驅動加載方面默認是
{自動}的,所以不用改了
產生問題1:
有了這個 .reg 就相當于 .inf? .reg 安裝驅動跟 .inf 安裝驅動方法的區別?
-- 未解決
3、運行 filedisk.reg 然后重啟
4、重啟后, 在cmd 窗體執行命令
filedisk /mount 0 c:\test.img 8M e:
5、此時,系統多出一個 e 盤,雙擊提示未格式化,格式化完 E 盤后,就可以像普通磁盤一樣操作了
產生問題1: 看了下設備管理器并沒有多出一個設備,那么E盤怎么出來的?
用 WinObj.exe 也無所發現 (先迷茫一下先!!!)
接下來,試下編譯 filedisk sys 的源程序
build filedisk 沒出現問題,生成了 check 的 filedisk.sys
然后,試下編譯 filedisk exe 的程序
在 exe 目錄下 nmake /f makefile ,卻出現錯誤提示
Microsoft (R) Program Maintenance Utility Version 6.00.9782.0
Copyright (C) Microsoft Corp 1988-1998. All rights reserved.

makefile(7) : fatal error U1052: file '\makefile.def' not found
Stop.
google了一下,找到方法
據說 exe 同樣用DDK的環境來編譯
在 filedisk 的 exe 目錄 build -cz
果然,編譯通過了生成了 filedisk.exe
產生問題1:
filedisk 的 exe 為何不能用 nmake 來編譯?
產生問題2:
ddk 也可以用來編譯 exe 程序?
產生問題3:
如果用 vc 建一個 Win32 Console Application 工程又能否編譯?
-- 試了一下,果然是可以滴!!
把自己編譯的 filedisk.sys 和 filedisk.exe 放到虛擬機試下是否正常先.
因為剛剛在前面已經設置了驅動是自動加載的,怕覆蓋 filedisk.sys 后,系統還是會用回原來的 filedisk.sys
于是重啟一下系統先~!
產生很奇怪的問題1:
用自己編譯的 exe && sys 運后,可以正常虛擬一個分區出來,但 win 提示不能格式化分區
-- 用原先的 exe 再試一下, 試過后, win 仍然提示不能格式化分區
于是用回 原先的 sys 再試一下,
突然間懷疑,是不是 映象文件的問題,因為我用的是
filedisk /mount 0 c:\test.txt 8M e:
后綴名是 .txt
改成 filedisk /mount 0 c:\test.img 8M e: 后 win 提示格式化分區成功,于是
產生很奇怪的問題2:
filedisk 的映象文件的后綴名如果為 .txt ,會導致 win 不能格式化虛擬出來的分區?
按道理應該跟映象文件的后綴名無關才是,估計要研究下里面的代碼才清楚了!!!
-- 未解決
另外還產生很奇怪的問題3:
我把映象文件的大小設置 1K, win會提示“無法完成格式化”,難道 win 需要空間存放文件分配表?
試了一下,映象文件的大小在 3M 左右,win才可以格式化成功,具體值無嘗試

另一方面,如果 windows 的分區在格式化時,它應該會建一個
{文件分配表}之類的東西,

而這個
{文件分配表}的大小應該跟分區的大小有關 (暫無找到相關的資料,未解決)
-- 未解決
大概看了下 filedisk.c 的代碼, 里面用的是
CreateFile + DeviceIoControl 的方法 跟 驅動通信
里面并沒有采用動態加載驅動
問題1:
如何動態加載驅動?
之前在網上看到的資料應該有“SM”之類的API可以動態加載驅動,
這個有時間再研究.

一個上午的時間就這樣被花光了!!!!!
然后再看下由 Bill Gates 說的(做file disk建議看filedisk的源代碼,在http://www.acc.umu.se/~bosse。)
在開始工作之前,先感謝一下 BillGates ,雖然他已經退休了,但居然光臨我的BLOG,



















































































問題1:
運行 TrueCrypt\Driver\BuildDriver.cmd ,不能編譯驅動,提示 "BuildDriver.cmd: error: Cannot copy target."
沒有時間看 ReadMe. 未解決
問題2:
將 TrueCrypt.sln 用工具轉換為 TrueCrypt.dsw ,打開后無論編譯哪一個工程,都會提示很多錯誤信息
未解決
問題3:
IoCreateDevice 最后一個參數 Returned ptr to Device Object, 是否需要為其分配空間
-- Answered by bill Bill Gates : Device Object對象由系統分配,系統會在這個對象reference count為0的時候自動銷毀。
安裝 filedisk 后
產生問題1: 看了下設備管理器并沒有多出一個設備,那么E盤怎么出來的?








產生很奇怪的問題1:






















