WINDOWS未公开函数揭密
这次介绍的是如何利用Windows未公开函数实现系统文件操作监视功能。利用该功能可以对Windows下的任何文件操作,包括建立文件、文件夹;删除文件;改变文件大小等操作都可以纪录在案。首先来介绍实现上面操作的两个未公开函数:SHChangeNotifyRegister和SHChangeNotifyDeregister,SHChangeNotifyRegister函数的定义如下:Declare Function SHChangeNotifyRegister Lib “shell32" Alias “#2" _(ByVal hWnd As Long, _ByVal uFlags As SHCN_ItemFlags, _ByVal dwEventID As SHCN_EventIDs, ByVal uMsg As Long, _ByVal cItems As Long, _lpps As PIDLSTRUCT) As Long其中参数hWnd指定接受系统通告的窗口句柄,参数uMsg指定消息值,如果函数调用成功,系统就会将hWnd指定的窗口加入到系统通告链中,并且返回系统通告句柄。当有建立文件等系统操作发生时,系统会向hWnd指定的窗口发送uMsg消息,关于其它参数,会在下面的程序中说明。函数SHChangeNotifyDeregister的定义如下:Declare Function SHChange Notify Deregister Lib“shell32" Alias “#4" _(ByVal hNotify As Long) As Boolean其中参数hNotify指定系统通告的句柄。下面是操作的具体的VB范例:首先建立一个新的工程,在Form1中加入一个TextBox控件。在Form1的代码窗口之中加入以下代码:Option ExplicitPrivate Sub Form_Load()If SubClass(hWnd) Then '改变Form1的消息处理函数If IsIDE ThenText1.Text = vbCrLf & _“一个 Windows的文件目录操作即时监视程序," & vbCrLf & “可以监视在Explore中的重命名、新建、删除文" & _vbCrLf & “件或目录;改变文件关联;插入、取出CD和添加“& vbCrLf & "删除网络共享都可以被该程序记录下来。"End IfCall SHNotify_Register(hWnd)ElseText1 =“系统不支持操作监视程序 :-)"End IfMove Screen.Width - Width, Screen.Height - HeightEnd SubPrivate Function IsIDE() As BooleanOn Error GoTo OutDebug.Print 1 / 0Out:IsIDE = ErrEnd FunctionPrivate Sub Form_Unload(Cancel As Integer)Call SHNotify_UnregisterCall UnSubClass(hWnd)End SubPublic Sub NotificationReceipt(wParam As Long, lParam As Long)Dim sOut As StringDim shns As SHNOTIFYSTRUCTDim sDisplayname1 As StringDim sDisplayname2 As StringMoveMemory shns, ByVal wParam, Len(shns)If shns.dwItem1 ThensDisplayname1 = GetDisplayNameFromPIDL(shns.dwItem1)End IfIf shns.dwItem2 ThensDisplayname2 = GetDisplayNameFromPIDL(shns.dwItem2)End IfsOut = SHNotify_ GetEvent Str(sDisplayname1, sDisplayname2, lParam) & vbCrLfText1 = Text1 & sOut & vbCrLfText1.SelStart = Len(Text1)End Sub然后在工程中加入三个模块(Bas)文件,将三个文件分别保存为mDef.Bas、mShell.Bas、mSub.Bas。在mDef.Bas中加入以下代码:'mDef.Bas包含Shell操作的函数和数据类型的定义Option ExplicitDeclare Sub MoveMemory Lib “kernel32" Alias“RtlMoveMemory" (pDest As Any, _pSource As Any, ByVal dwLength As Long)Declare Sub CoTaskMemFree Lib “ole32.dll" (ByVal pv As Long)Public Const MAX_PATH = 260Public Const NOERROR = 0'SHGetSpecialFolderLocation获得某一个特殊的目录的位置,如果函数调用成功返回NOERROR'或者一个OLE错误Declare Function SHGetSpecialFolderLocation Lib “shell32.dll" _(ByVal hwndOwner As Long, _ByVal nFolder As SHSpecialFolderIDs, _pidl As Long) As LongPublic Enum SHSpecialFolderIDs '列出所有Windows下特殊文件夹的IDCSIDL_DESKTOP = &H0CSIDL_INTERNET = &H1CSIDL_PROGRAMS = &H2CSIDL_CONTROLS = &H3CSIDL_PRINTERS = &H4CSIDL_PERSONAL = &H5CSIDL_FAVORITES = &H6CSIDL_STARTUP = &H7CSIDL_RECENT = &H8CSIDL_SENDTO = &H9CSIDL_BITBUCKET = &HACSIDL_STARTMENU = &HBCSIDL_DESKTOPDIRECTORY = &H10CSIDL_DRIVES = &H11CSIDL_NETWORK = &H12CSIDL_NETHOOD = &H13CSIDL_FONTS = &H14CSIDL_TEMPLATES = &H15CSIDL_COMMON_STARTMENU = &H16CSIDL_COMMON_PROGRAMS = &H17CSIDL_COMMON_STARTUP = &H18CSIDL_COMMON_DESKTOPDIRECTORY = &H19CSIDL_APPDATA = &H1ACSIDL_PRINTHOOD = &H1BCSIDL_ALTSTARTUP = &H1DCSIDL_COMMON_ALTSTARTUP = &H1ECSIDL_COMMON_FAVORITES = &H1FCSIDL_INTERNET_CACHE = &H20CSIDL_COOKIES = &H21CSIDL_HISTORY = &H22End Enum'SHGetPathFromIDList函数将一个Item转换为文件路径Declare Function SHGetPathFromIDList Lib“shell32.dll" Alias “SHGetPathFromIDListA" _(ByVal pidl As Long, _ByVal pszPath As String) As Long'SHGetFileInfoPidl函数获得某个文件对象的信息。Declare Function SHGetFileInfoPidl Lib “shell32" Alias“SHGetFileInfoA" (ByVal pidl As Long, _ByVal dwFileAttributes As Long, _psfib As SHFILEINFOBYTE, _ByVal cbFileInfo As Long, _ByVal uFlags As SHGFI_flags) As LongPublic Type SHFILEINFOBYTEhIcon As LongiIcon As LongdwAttributes As LongszDisplayName(1 To MAX_PATH) As ByteszTypeName(1 To 80) As ByteEnd TypeDeclare Function SHGetFileInfo Lib “shell32" Alias “SHGetFileInfoA" _(ByVal pszPath As String, _ByVal dwFileAttributes As Long, _psfi As SHFILEINFO, _ByVal cbFileInfo As Long, _ByVal uFlags As SHGFI_flags) As LongPublic Type SHFILEINFOhIcon As LongiIcon As LongdwAttributes As LongszDisplayName As String * MAX_PATHszTypeName As String * 80End TypeEnum SHGFI_flagsSHGFI_LARGEICON = &H0SHGFI_SMALLICON = &H1SHGFI_OPENICON = &H2SHGFI_SHELLICONSIZE = &H4SHGFI_PIDL = &H8SHGFI_USEFILEATTRIBUTES = &H10SHGFI_ICON = &H100SHGFI_DISPLAYNAME = &H200SHGFI_TYPENAME = &H400SHGFI_ATTRIBUTES = &H800SHGFI_ICONLOCATION = &H1000SHGFI_EXETYPE = &H2000SHGFI_SYSICONINDEX = &H4000SHGFI_LINKOVERLAY = &H8000SHGFI_SELECTED = &H10000End Enum