📄 udynlink.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: UDynLink.cpp,v 1.6 2002/08/06 20:10:46 dallen Exp $
____________________________________________________________________________*/
#include "pgpClassesConfig.h"
#include "UDynLink.h"
_USING_PGP
_UNNAMED_BEGIN
// Types
typedef long (_stdcall * BroadcastSystemMessageType)(DWORD, LPDWORD,
UINT, WPARAM, LPARAM);
typedef BOOL (_stdcall * GetDiskFreeSpaceExType)(LPCTSTR,
PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
typedef DWORD (_stdcall * Win95_NetShareGetInfoType)(const char FAR *,
const char FAR *, short, char FAR *, unsigned short,
unsigned short FAR *);
typedef DWORD (_stdcall * Win95_WNetCloseEnumType)(HANDLE);
typedef DWORD (_stdcall * Win95_WNetEnumResourceType)(HANDLE, LPDWORD,
LPVOID, LPDWORD);
typedef DWORD (_stdcall * Win95_WNetOpenEnumType)(DWORD, DWORD, DWORD,
LPNETRESOURCE, LPHANDLE);
typedef VOID (_stdcall * WinNT_FormatExType)(PWCHAR, DWORD, PWCHAR,
PWCHAR, BOOL, DWORD, UDynLink::PFMIFSCALLBACK);
typedef DWORD (_stdcall * WinNT_NetApiBufferFreeType)(LPVOID);
typedef DWORD (_stdcall * WinNT_NetShareGetInfoType)(LPWSTR, LPWSTR,
DWORD, LPBYTE *);
typedef DWORD (_stdcall * WinNT_WNetGetUniversalNameType)(LPCTSTR,
DWORD, LPVOID, LPDWORD);
typedef BOOL (_stdcall * WinNT_OpenProcessTokenType)(HANDLE, DWORD, PHANDLE);
typedef BOOL (_stdcall * WinNT_OpenThreadTokenType)(HANDLE, DWORD, BOOL,
PHANDLE);
typedef BOOL (_stdcall * WinNT_GetTokenInformationType)(HANDLE,
TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD);
typedef BOOL (_stdcall * WinNT_AllocateAndInitializeSidType)(
PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD,
DWORD, DWORD, DWORD, PSID *);
typedef BOOL (_stdcall * WinNT_EqualSidType)(PSID, PSID);
typedef PVOID (_stdcall * WinNT_FreeSidType)(PSID);
typedef BOOL (_stdcall * Win2k_GetVolumeNameForVolumeMountPointType)(
LPCTSTR, LPTSTR, DWORD);
typedef BOOL (_stdcall * Win2k_GetVolumePathNameType)(LPCTSTR, LPTSTR, DWORD);
typedef BOOL (_stdcall * Win2k_SetVolumeMountPointType)(LPCTSTR, LPCTSTR);
typedef BOOL (_stdcall * Win2k_DeleteVolumeMountPointType)(LPCTSTR);
// Static variables
HINSTANCE Advapi32Handle;
HINSTANCE FmifsHandle;
HINSTANCE Kernel32Handle;
HINSTANCE MprHandle;
HINSTANCE NetApi32Handle;
HINSTANCE SvrApiHandle;
HINSTANCE User32Handle;
BroadcastSystemMessageType BroadcastSystemMessageAddr;
GetDiskFreeSpaceExType GetDiskFreeSpaceExAddr;
Win95_NetShareGetInfoType Win95_NetShareGetInfoAddr;
Win95_WNetCloseEnumType Win95_WNetCloseEnumAddr;
Win95_WNetEnumResourceType Win95_WNetEnumResourceAddr;
Win95_WNetOpenEnumType Win95_WNetOpenEnumAddr;
WinNT_FormatExType WinNT_FormatExAddr;
WinNT_NetApiBufferFreeType WinNT_NetApiBufferFreeAddr;
WinNT_NetShareGetInfoType WinNT_NetShareGetInfoAddr;
WinNT_WNetGetUniversalNameType WinNT_WNetGetUniversalNameAddr;
WinNT_OpenProcessTokenType WinNT_OpenProcessTokenAddr;
WinNT_OpenThreadTokenType WinNT_OpenThreadTokenAddr;
WinNT_GetTokenInformationType WinNT_GetTokenInformationAddr;
WinNT_AllocateAndInitializeSidType WinNT_AllocateAndInitializeSidAddr;
WinNT_EqualSidType WinNT_EqualSidAddr;
WinNT_FreeSidType WinNT_FreeSidAddr;
Win2k_GetVolumeNameForVolumeMountPointType
Win2k_GetVolumeNameForVolumeMountPointAddr;
Win2k_GetVolumePathNameType Win2k_GetVolumePathNameAddr;
Win2k_SetVolumeMountPointType Win2k_SetVolumeMountPointAddr;
Win2k_DeleteVolumeMountPointType Win2k_DeleteVolumeMountPointAddr;
// Static functions
void
LoadAdvapi32()
{
if (IsNull(Advapi32Handle))
{
Advapi32Handle = LoadLibrary("advapi32.dll");
if (IsNull(Advapi32Handle))
THROW_ERRORS(kPGPError_Win32DllOpFailed, GetLastError());
}
}
void
LoadFmifs()
{
if (IsNull(FmifsHandle))
{
FmifsHandle = LoadLibrary("fmifs.dll");
if (IsNull(FmifsHandle))
THROW_ERRORS(kPGPError_Win32DllOpFailed, GetLastError());
}
}
void
LoadKernel32()
{
if (IsNull(Kernel32Handle))
{
Kernel32Handle = LoadLibrary("kernel32.dll");
if (IsNull(Kernel32Handle))
THROW_ERRORS(kPGPError_Win32DllOpFailed, GetLastError());
}
}
void
LoadMpr()
{
if (IsNull(MprHandle))
{
MprHandle = LoadLibrary("mpr.dll");
if (IsNull(MprHandle))
THROW_ERRORS(kPGPError_Win32DllOpFailed, GetLastError());
}
}
void
LoadNetApi32()
{
if (IsNull(Kernel32Handle))
{
NetApi32Handle = LoadLibrary("netapi32.dll");
if (IsNull(NetApi32Handle))
THROW_ERRORS(kPGPError_Win32DllOpFailed, GetLastError());
}
}
void
LoadSvrApi()
{
if (IsNull(Kernel32Handle))
{
SvrApiHandle = LoadLibrary("svrapi.dll");
if (IsNull(SvrApiHandle))
THROW_ERRORS(kPGPError_Win32DllOpFailed, GetLastError());
}
}
void
LoadUser32()
{
if (IsNull(Kernel32Handle))
{
User32Handle = LoadLibrary("user32.dll");
if (IsNull(User32Handle))
THROW_ERRORS(kPGPError_Win32DllOpFailed, GetLastError());
}
}
_UNNAMED_END
// Exported functions
long
UDynLink::BroadcastSystemMessage(
DWORD dwFlags,
LPDWORD lpdwRecipients,
UINT uiMessage,
WPARAM wParam,
LPARAM lParam)
{
if (IsNull(BroadcastSystemMessageAddr))
{
LoadUser32();
BroadcastSystemMessageAddr =
reinterpret_cast<BroadcastSystemMessageType>(
GetProcAddress(User32Handle, "BroadcastSystemMessage"));
if (IsNull(BroadcastSystemMessageAddr))
THROW_ERRORS(kPGPError_Win32DllOpFailed, GetLastError());
}
long result = BroadcastSystemMessageAddr(dwFlags,
lpdwRecipients, uiMessage, wParam, lParam);
return result;
}
BOOL
UDynLink::GetDiskFreeSpaceEx(
LPCTSTR lpDirectoryName,
PULARGE_INTEGER lpFreeBytesAvailableToCaller,
PULARGE_INTEGER lpTotalNumberOfBytes,
PULARGE_INTEGER lpTotalNumberOfFreeBytes)
{
if (IsNull(GetDiskFreeSpaceExAddr))
{
LoadKernel32();
#if defined(_UNICODE)
GetDiskFreeSpaceExAddr = reinterpret_cast<GetDiskFreeSpaceExType>(
GetProcAddress(Kernel32Handle, "GetDiskFreeSpaceExW"));
#else // !_UNICODE
GetDiskFreeSpaceExAddr = reinterpret_cast<GetDiskFreeSpaceExType>(
GetProcAddress(Kernel32Handle, "GetDiskFreeSpaceExA"));
#endif // _UNICODE
if (IsNull(GetDiskFreeSpaceExAddr))
THROW_ERRORS(kPGPError_Win32DllOpFailed, GetLastError());
}
BOOL result = GetDiskFreeSpaceExAddr(lpDirectoryName,
lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes,
lpTotalNumberOfFreeBytes);
return result;
}
DWORD
UDynLink::Win95_NetShareGetInfo(
const char FAR *pszServer,
const char FAR *pszNetName,
short sLevel,
char FAR *pbBuffer,
unsigned short cbBuffer,
unsigned short FAR *pcbTotalAvail)
{
if (IsNull(Win95_NetShareGetInfoAddr))
{
LoadSvrApi();
Win95_NetShareGetInfoAddr = reinterpret_cast<
Win95_NetShareGetInfoType>(GetProcAddress(SvrApiHandle,
"NetShareGetInfo"));
if (IsNull(Win95_NetShareGetInfoAddr))
THROW_ERRORS(kPGPError_Win32DllOpFailed, GetLastError());
}
return Win95_NetShareGetInfoAddr(pszServer, pszNetName, sLevel,
pbBuffer, cbBuffer, pcbTotalAvail);
}
DWORD
UDynLink::Win95_WNetCloseEnum(HANDLE hEnum)
{
if (IsNull(Win95_WNetCloseEnumAddr))
{
LoadMpr();
Win95_WNetCloseEnumAddr = reinterpret_cast<Win95_WNetCloseEnumType>(
GetProcAddress(MprHandle, "WNetCloseEnum"));
if (IsNull(Win95_WNetCloseEnumAddr))
THROW_ERRORS(kPGPError_Win32DllOpFailed, GetLastError());
}
return Win95_WNetCloseEnumAddr(hEnum);
}
DWORD
UDynLink::Win95_WNetEnumResource(
HANDLE hEnum,
LPDWORD lpcCount,
LPVOID lpBuffer,
LPDWORD lpBufferSize)
{
if (IsNull(Win95_WNetEnumResourceAddr))
{
LoadMpr();
#if defined(_UNICODE)
Win95_WNetEnumResourceAddr =
reinterpret_cast<Win95_WNetEnumResourceType>(
GetProcAddress(MprHandle, "WNetEnumResourceW"));
#else // !_UNICODE
Win95_WNetEnumResourceAddr =
reinterpret_cast<Win95_WNetEnumResourceType>(
GetProcAddress(MprHandle, "WNetEnumResourceA"));
#endif // _UNICODE
if (IsNull(Win95_WNetEnumResourceAddr))
THROW_ERRORS(kPGPError_Win32DllOpFailed, GetLastError());
}
return Win95_WNetEnumResourceAddr(hEnum, lpcCount, lpBuffer,
lpBufferSize);
}
// Win95_WNetGetUniversalName implements a hack under Windows95 that
// simulates the non-working WNetGetUniversalName (from KB Article ID:
// Q131416).
BOOL
UDynLink::Win95_WNetGetUniversalName(LPCSTR szDrive, LPTSTR szUniv)
{
// get the local drive letter
char chLocal = toupper(szDrive[0]);
// cursory validation
if (chLocal < 'A' || chLocal > 'Z')
return FALSE;
if (szDrive[1] != ':' || szDrive[2] != '\\')
return FALSE;
HANDLE hEnum;
DWORD dwResult = Win95_WNetOpenEnum(RESOURCE_CONNECTED,
RESOURCETYPE_DISK, 0, NULL, &hEnum);
if (dwResult != NO_ERROR)
return FALSE;
// request all available entries
const int c_cEntries = 0xFFFFFFFF;
// start with a reasonable buffer size
DWORD cbBuffer = 50 * sizeof(NETRESOURCE);
NETRESOURCE *pNetResource = static_cast<NETRESOURCE *>(malloc(cbBuffer));
BOOL fResult = FALSE;
while (TRUE)
{
DWORD dwSize = cbBuffer,
cEntries = c_cEntries;
dwResult = Win95_WNetEnumResource(hEnum, &cEntries, pNetResource,
&dwSize);
if (dwResult == ERROR_MORE_DATA)
{
// the buffer was too small, enlarge
cbBuffer = dwSize;
pNetResource = static_cast<NETRESOURCE*>(
realloc(pNetResource, cbBuffer));
continue;
}
if (dwResult != NO_ERROR)
goto done;
// search for the specified drive letter
for (int i = 0; i < static_cast<int>(cEntries); i++)
if (pNetResource[i].lpLocalName &&
chLocal == toupper(pNetResource[i].lpLocalName[0]))
{
// match
fResult = TRUE;
// build a UNC name
strcpy(szUniv, pNetResource[i].lpRemoteName);
strcat(szUniv, szDrive + 2);
_strupr(szUniv);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -