windows-nt/Source/XPSP1/NT/shell/ext/hnw/wizard/mysvrapi.cpp
2020-09-26 16:20:57 +08:00

480 lines
11 KiB
C++

//
// MySvrApi.cpp
//
// Thunk layer for SVRAPI.DLL (Win9x and NT)
//
//
#include "stdafx.h"
#include "mysvrapi.h"
#include "TheApp.h"
#include "cstrinout.h"
#include <lm.h>
//
// Conversion classes.
//
class CShareInfo50to502
{
public:
CShareInfo50to502(LPBYTE* ppBuff) {_ppBuffOut = ppBuff;}
operator char*() {return _aBuffIn;}
USHORT SizeOfBuffer() {return sizeof(_aBuffIn);}
BOOL Convert();
protected:
CShareInfo50to502() {};
ULONG SizeRequired(const share_info_50* psi50);
void CopyData(const share_info_50* psi50, SHARE_INFO_502* psi502, WCHAR** ppsz, ULONG* pcch);
private:
void CopyStringAndAdvancePointer(LPCSTR pszSrc, LPWSTR* ppszDst, ULONG* pcch);
DWORD ConvertPermissions(USHORT shi50_flags);
private:
BYTE** _ppBuffOut;
char _aBuffIn[sizeof(share_info_50) + 2*MAX_PATH];
};
ULONG CShareInfo50to502::SizeRequired(const share_info_50* psi50)
{
ULONG cb = sizeof(SHARE_INFO_502);
cb += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, psi50->shi50_netname, -1, NULL, 0);
cb += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, (psi50->shi50_remark ? psi50->shi50_remark : ""), -1, NULL, 0);
cb += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, (psi50->shi50_path ? psi50->shi50_path : ""), -1, NULL, 0);
cb += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, psi50->shi50_rw_password, -1, NULL, 0);
return cb;
}
void CShareInfo50to502::CopyStringAndAdvancePointer(LPCSTR pszSrc, LPWSTR* ppszDst, ULONG* pcch)
{
int cch = SHAnsiToUnicode(pszSrc, *ppszDst, *pcch);
*ppszDst += cch;
*pcch -= cch;
}
DWORD CShareInfo50to502::ConvertPermissions(USHORT shi50_flags)
{
DWORD dwRet;
if (shi50_flags & SHI50F_FULL)
{
dwRet = ACCESS_ALL;
}
else if (shi50_flags & SHI50F_RDONLY)
{
dwRet = ACCESS_READ;
}
else
{
dwRet = 0;
}
return dwRet | SHI50F_PERSIST;
}
void CShareInfo50to502::CopyData(const share_info_50* psi50, SHARE_INFO_502* psi502, WCHAR** ppsz, ULONG* pcch)
{
psi502->shi502_type = psi50->shi50_type;
psi502->shi502_permissions = ConvertPermissions(psi50->shi50_flags);
psi502->shi502_max_uses = 0;
psi502->shi502_current_uses = 0;
psi502->shi502_reserved = 0;
psi502->shi502_security_descriptor = NULL;
psi502->shi502_netname = *ppsz;
CopyStringAndAdvancePointer(psi50->shi50_netname, ppsz, pcch);
psi502->shi502_remark = *ppsz;
CopyStringAndAdvancePointer(psi50->shi50_remark, ppsz, pcch);
psi502->shi502_path = *ppsz;
CopyStringAndAdvancePointer(psi50->shi50_path, ppsz, pcch);
psi502->shi502_passwd = *ppsz;
CopyStringAndAdvancePointer(psi50->shi50_rw_password, ppsz, pcch);
}
BOOL CShareInfo50to502::Convert()
{
ULONG cb = SizeRequired((share_info_50*)_aBuffIn);
*_ppBuffOut = (BYTE*)LocalAlloc(LPTR, cb);
if (*_ppBuffOut)
{
WCHAR* psz = (WCHAR*)((BYTE*)*_ppBuffOut + sizeof(SHARE_INFO_502));
ULONG cch = (cb - sizeof(SHARE_INFO_502)) / sizeof(WCHAR);
CopyData((share_info_50*)_aBuffIn, (SHARE_INFO_502*)*_ppBuffOut, &psz, &cch);
}
return (*_ppBuffOut != NULL);
}
//
//
//
class CMultiShareInfo50to502 : public CShareInfo50to502
{
public:
CMultiShareInfo50to502(BYTE** ppBuff, const char* pData, ULONG nItems);
BOOL Convert();
private:
ULONG MultiSizeRequired();
void MultiCopyData(ULONG cb);
private:
SHARE_INFO_502** _ppBuffOut;
const share_info_50* _pDataIn;
ULONG _nItems;
};
CMultiShareInfo50to502::CMultiShareInfo50to502(BYTE** ppBuff, const char* pData, ULONG nItems)
{
_ppBuffOut = (SHARE_INFO_502**)ppBuff;
_pDataIn = (share_info_50*)pData;
_nItems = nItems;
}
ULONG CMultiShareInfo50to502::MultiSizeRequired()
{
ULONG cbRet = 0;
for (ULONG i = 0; i < _nItems; i++)
cbRet += SizeRequired(&_pDataIn[i]);
return cbRet;
}
void CMultiShareInfo50to502::MultiCopyData(ULONG cb)
{
WCHAR* psz = (WCHAR*)((BYTE*)*_ppBuffOut + (sizeof(SHARE_INFO_502) * _nItems));
ULONG cch = (cb - (sizeof(SHARE_INFO_502) * _nItems)) / sizeof(WCHAR);
for (ULONG i = 0; i < _nItems; i++)
CopyData(&_pDataIn[i], &(*_ppBuffOut)[i], &psz, &cch);
}
BOOL CMultiShareInfo50to502::Convert()
{
ULONG cb = MultiSizeRequired();
*_ppBuffOut = (SHARE_INFO_502*)LocalAlloc(LPTR, cb);
if (*_ppBuffOut)
{
MultiCopyData(cb);
}
return *_ppBuffOut != NULL;
}
//
//
//
class CShareInfo502to50
{
public:
CShareInfo502to50(BYTE* pBuff) {_pBuffIn = pBuff;}
operator char*();
WORD SizeOfBuffer() {return sizeof(_aBuff);}
private:
void CopyData();
void CopyStringAndAdvancePointer(LPCWSTR pszSrc, LPSTR* ppszDst, ULONG* pcch);
WORD ConvertPermissions(DWORD shi502_permissions);
private:
BYTE* _pBuffIn;
BYTE _aBuff[sizeof(share_info_50) + 256];
};
WORD CShareInfo502to50::ConvertPermissions(DWORD shi502_permissions)
{
WORD wRet;
if (shi502_permissions & (ACCESS_ALL ^ ACCESS_READ))
{
wRet = SHI50F_FULL;
}
else if (shi502_permissions & ACCESS_READ)
{
wRet = SHI50F_RDONLY;
}
else
{
wRet = 0;
}
return wRet | SHI50F_PERSIST; // Always persist share info.
}
void CShareInfo502to50::CopyStringAndAdvancePointer(LPCWSTR pszSrc, LPSTR* ppszDst, ULONG* pcch)
{
int cch = SHUnicodeToAnsi(pszSrc, *ppszDst, *pcch);
*ppszDst += cch;
*pcch -= cch;
}
void CShareInfo502to50::CopyData()
{
share_info_50* psi50 = (share_info_50*)_aBuff;
SHARE_INFO_502* psi502 = (SHARE_INFO_502*)_pBuffIn;
char* psz = (char*)(_aBuff + sizeof(share_info_50));
ULONG cch = ARRAYSIZE(_aBuff) - sizeof(share_info_50);
psi50->shi50_type = (BYTE)psi502->shi502_type;
psi50->shi50_flags = ConvertPermissions(psi502->shi502_permissions);
psi50->shi50_ro_password[0] = '\0';
WideCharToMultiByte(CP_ACP, 0, psi502->shi502_netname, -1, psi50->shi50_netname,
ARRAYSIZE(psi50->shi50_netname), NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, psi502->shi502_passwd, -1, psi50->shi50_rw_password,
ARRAYSIZE(psi50->shi50_rw_password), NULL, NULL);
if (psi502->shi502_remark)
{
psi50->shi50_remark = psz;
CopyStringAndAdvancePointer(psi502->shi502_remark, &psz, &cch);
}
else
{
psi50->shi50_remark = NULL;
}
if (psi502->shi502_path)
{
psi50->shi50_path = psz;
CopyStringAndAdvancePointer(psi502->shi502_path, &psz, &cch);
}
else
{
psi502->shi502_path = NULL;
}
}
CShareInfo502to50::operator char*()
{
char* pRet;
if (_pBuffIn)
{
CopyData();
pRet = (char*)_aBuff;
}
else
{
pRet = NULL;
}
return pRet;
}
//
//
//
NET_API_STATUS NetShareEnumWrap(LPCTSTR pszServer, DWORD level, LPBYTE * ppBuffer, DWORD dwPrefMaxLen, LPDWORD pdwEntriesRead, LPDWORD pdwTotalEntries, LPDWORD dsResumeHandle)
{
ASSERTMSG(502==level, "NetShareEnumWrap doesn't thunk the requestesd buffer level");
NET_API_STATUS nasRet;
if (!theApp.IsWindows9x())
{
nasRet = NetShareEnum_NT((LPWSTR)pszServer, level, ppBuffer, dwPrefMaxLen, pdwEntriesRead, pdwTotalEntries, dsResumeHandle);
}
else
{
CStrIn cstrServer(pszServer);
USHORT cb = sizeof(share_info_50) + (2 * MAX_PATH);
char* pData = (char*)LocalAlloc(LPTR, cb);
if (pData)
{
*pdwEntriesRead = *pdwTotalEntries = 0;
nasRet = NetShareEnum_W95(cstrServer, 50, pData, cb, (USHORT*)pdwEntriesRead, (USHORT*)pdwTotalEntries);
if (*pdwEntriesRead < *pdwTotalEntries)
{
LocalFree(pData);
cb = (USHORT)((sizeof(share_info_50) + (2 * MAX_PATH)) * (*pdwTotalEntries));
pData = (char*)LocalAlloc(LPTR, cb);
if (pData)
{
nasRet = NetShareEnum_W95(cstrServer, 50, pData, cb, (USHORT*)pdwEntriesRead, (USHORT*)pdwTotalEntries);
}
}
if (NERR_Success == nasRet)
{
CMultiShareInfo50to502 cmnsio(ppBuffer, pData, *pdwEntriesRead);
if (!cmnsio.Convert())
nasRet = ERROR_NOT_ENOUGH_MEMORY;
}
LocalFree(pData);
}
else
{
nasRet = ERROR_NOT_ENOUGH_MEMORY;
}
}
return nasRet;
}
NET_API_STATUS NetShareAddWrap(LPCTSTR pszServer, DWORD level, LPBYTE buffer)
{
ASSERTMSG(502==level, "NetShareAddWrap doesn't thunk the requested buffer level");
NET_API_STATUS nasRet;
if (!theApp.IsWindows9x())
{
nasRet = NetShareAdd_NT((LPTSTR)pszServer, level, buffer, NULL);
}
else
{
if (502 == level)
{
CStrIn cstrServer(pszServer);
CShareInfo502to50 CSI(buffer);
nasRet = NetShareAdd_W95(cstrServer, 50, CSI, sizeof(share_info_50));
}
else
{
nasRet = ERROR_INVALID_LEVEL;
}
}
return nasRet;
}
NET_API_STATUS NetShareDelWrap(LPCTSTR pszServer, LPCTSTR pszNetName, DWORD reserved)
{
ASSERTMSG(0==reserved, "NetShareDelWrap called with non-zero reserved parameter");
NET_API_STATUS nasRet;
if (!theApp.IsWindows9x())
{
nasRet = NetShareDel_NT((LPTSTR)pszServer, (LPTSTR)pszNetName, 0);
}
else
{
CStrIn cstrServer(pszServer);
CStrIn cstrNetName(pszNetName);
nasRet = NetShareDel_W95(cstrServer, cstrNetName, 0);
}
return nasRet;
}
NET_API_STATUS NetShareGetInfoWrap(LPCTSTR pszServer, LPCTSTR pszNetName, DWORD level, LPBYTE * ppbuffer)
{
NET_API_STATUS nasRet;
if (!theApp.IsWindows9x())
{
nasRet = NetShareGetInfo_NT((LPTSTR)pszServer, (LPTSTR)pszNetName, level, ppbuffer);
}
else
{
if (502==level)
{
CShareInfo50to502 CNSIOut(ppbuffer);
CStrIn cstrServer(pszServer);
CStrIn cstrNetName(pszNetName);
USHORT n;
nasRet = NetShareGetInfo_W95(cstrServer, cstrNetName, 50, CNSIOut, CNSIOut.SizeOfBuffer(), &n);
if (NERR_Success == nasRet)
{
if (!CNSIOut.Convert())
nasRet = ERROR_NOT_ENOUGH_MEMORY;
}
}
else
{
*ppbuffer = NULL;
nasRet = ERROR_INVALID_LEVEL;
}
}
return nasRet;
}
NET_API_STATUS NetShareSetInfoWrap(LPCTSTR pszServer, LPCTSTR pszNetName, DWORD level, LPBYTE buffer)
{
NET_API_STATUS nasRet;
if (!theApp.IsWindows9x())
{
nasRet = NetShareSetInfo_NT((LPTSTR)pszServer, (LPTSTR)pszNetName, level, buffer, NULL);
}
else
{
if (502==level)
{
CStrIn cstrServer(pszServer);
CStrIn cstrNetName(pszNetName);
CShareInfo502to50 CNSI(buffer);
nasRet = NetShareSetInfo_W95(cstrServer, cstrNetName, 50, CNSI, sizeof(share_info_50), NULL);
}
else
{
nasRet = ERROR_INVALID_LEVEL;
}
}
return nasRet;
}
NET_API_STATUS NetApiBufferFreeWrap(LPVOID p)
{
NET_API_STATUS nasRet;
if (p)
{
if (!theApp.IsWindows9x())
{
nasRet = NetApiBufferFree_NT(p);
}
else
{
LocalFree(p);
nasRet = NERR_Success;
}
}
else
{
nasRet = NERR_Success;
}
return nasRet;
}