上一章讲到监控文件变化之函数 ReadDirectoryChangesW 要用到结构体FILE_NOTIFY_INFORMATION

该结构体定义如下:

typedef struct _FILE_NOTIFY_INFORMATION {
        DWORD NextEntryOffset;
        DWORD Action;
        DWORD FileNameLength;
        WCHAR FileName[1];
} FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION;

可以看到,FileName是一个固定大小字符数组,他的大小是1;FileNameLength为第一个字符串的长度,从FileName首地址开始的FileNameLength个字符都属于第一个字符串;

NextEntryOffset为偏移量,从FileName首地址开始,偏移NextEntryOffset后,直到其有效长度内,提取出来就可以得到第二个字符串。

 

在上一章是这样使用的:

char notify[1024]; 
memset(notify, 0, sizeof(notify)); 
FILE_NOTIFY_INFORMATION *pNotification=(FILE_NOTIFY_INFORMATION *)notify; 

也就是说对pNotification对象进行了填充,填充后的长度为1024字节,明显大于其原有长度,类似这种就是柔性数组。

pNotification是以指针的方式,将一段已经分配好的内存强制转换成FILE_NOTIFY_INFORMATION *格式,由于最后一个成员FileName的定义是字符数组,而字符数组的规矩是遇到零字符结束,所以只要FileName[0]和后面紧跟的字符不是非零字符,他的引用就不会结束,直到遇到零字符。

而ReadDirectoryChangesW 是一个 "W"例程,它使用的是Unicode。这个例程没有 ANSI 版本。因此,数据缓冲区自然也是Unicode。字符串不是 NULL 结尾的。

所以FileName的引用大小最大可以达到1024 - 3 * sizeof(DWORD)的大小。

 

获取pNotification的第一个字符串的方法如下:

CString szFileName(pNotification->FileName, pNotification->FileNameLength / sizeof(wchar_t));

  

获取第二个字符串的方法如下:

TCHAR newName[1024]={0};
ZeroMemory(newName, sizeof(newName));
int length = sizeof(notify) - pNotification->NextEntryOffset;
CopyMemory(newName, pNotification->FileName + pNotification->NextEntryOffset / sizeof(wchar_t), length);

  

以上都是我个人的理解,如有错误,欢迎指出。

posted on 2016-04-29 18:21  Love流浪的猪  阅读(2418)  评论(0)    收藏  举报