806 lines
24 KiB
C++
806 lines
24 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1993.
|
|
//
|
|
// File: api.cxx
|
|
//
|
|
// Contents: Exported APIs from this DLL
|
|
//
|
|
// History: 5-Oct-95 BruceFo Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "headers.hxx"
|
|
#pragma hdrstop
|
|
|
|
#include "resource.h"
|
|
#include "dllmain.hxx"
|
|
#include "shrpage.hxx"
|
|
#include "shrinfo.hxx"
|
|
#include "cache.hxx"
|
|
#include "util.hxx"
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
static BOOL WINAPI
|
|
SharingDialogHelp(
|
|
HWND hwndParent,
|
|
LPWSTR pszPath // this is 'new' memory that I take ownership of
|
|
);
|
|
|
|
//--------------------------------------------------------------------------
|
|
// A couple macros to use a stack buffer if smaller than a default size,
|
|
// else use a heap buffer.
|
|
|
|
// Example:
|
|
// LPWSTR pBuffer;
|
|
// DWORD dwBufLen;
|
|
// GET_BUFFER(pBuffer, dwBufLen, WCHAR, wcslen(pszString) + 1, MAX_PATH);
|
|
// if (NULL == pBuffer) { return NULL; } // couldn't get the buffer
|
|
// ... play with pBuffer
|
|
// FREE_BUFFER(pBuffer);
|
|
|
|
#define GET_BUFFER(pBuffer, dwBufLen, type, desiredLen, defaultLen) \
|
|
DWORD __desiredLen ## pBuffer = desiredLen; \
|
|
type __szTmpBuffer ## pBuffer[defaultLen]; \
|
|
if (__desiredLen ## pBuffer <= defaultLen) \
|
|
{ \
|
|
pBuffer = __szTmpBuffer ## pBuffer; \
|
|
dwBufLen = defaultLen; \
|
|
} \
|
|
else \
|
|
{ \
|
|
pBuffer = new type[__desiredLen ## pBuffer]; \
|
|
if (NULL != pBuffer) \
|
|
{ \
|
|
dwBufLen = __desiredLen ## pBuffer; \
|
|
} \
|
|
}
|
|
|
|
#define FREE_BUFFER(pBuffer) \
|
|
if (__szTmpBuffer ## pBuffer != pBuffer) { delete[] pBuffer; }
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: IsPathSharedW
|
|
//
|
|
// Synopsis: IsPathShared is used by the shell to determine whether to
|
|
// put a "shared folder / hand" icon next to a directory.
|
|
// Different from Windows 95, we don't allow sharing remote
|
|
// directories (e.g., \\brucefo4\c$\foo\bar style paths).
|
|
//
|
|
// Arguments: [lpcszPath] - path to look for
|
|
// [bRefresh] - TRUE if cache should be refreshed
|
|
//
|
|
// Returns: TRUE if the path is shared, FALSE otherwise
|
|
//
|
|
// History: 4-Apr-95 BruceFo Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL WINAPI
|
|
IsPathSharedW(
|
|
LPCWSTR lpcszPath,
|
|
BOOL bRefresh
|
|
)
|
|
{
|
|
InterlockedIncrement((long*)&g_NonOLEDLLRefs);
|
|
|
|
appDebugOut((DEB_TRACE,"IsPathSharedW(%ws, %d)\n", lpcszPath, bRefresh));
|
|
|
|
OneTimeInit();
|
|
BOOL bSuccess = g_ShareCache.IsPathShared(lpcszPath, bRefresh);
|
|
|
|
appDebugOut((DEB_TRACE,
|
|
"IsPathShared(%ws, %ws) = %ws\n",
|
|
lpcszPath,
|
|
bRefresh ? L"refresh" : L"no refresh",
|
|
bSuccess ? L"yes" : L"no"));
|
|
|
|
InterlockedDecrement((long*)&g_NonOLEDLLRefs);
|
|
return bSuccess;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: IsPathSharedA
|
|
//
|
|
// Synopsis: See IsPathSharedW
|
|
//
|
|
// Arguments: See IsPathSharedW
|
|
//
|
|
// Returns: See IsPathSharedW
|
|
//
|
|
// History: 1-Mar-96 BruceFo Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL WINAPI
|
|
IsPathSharedA(
|
|
LPCSTR lpcszPath,
|
|
BOOL bRefresh
|
|
)
|
|
{
|
|
InterlockedIncrement((long*)&g_NonOLEDLLRefs);
|
|
appDebugOut((DEB_TRACE,"IsPathSharedA(%s, %d)\n", lpcszPath, bRefresh));
|
|
|
|
if (NULL == lpcszPath)
|
|
{
|
|
return FALSE; // invalid input!
|
|
}
|
|
|
|
LPWSTR pszTmp;
|
|
DWORD dwBufLen;
|
|
GET_BUFFER(pszTmp, dwBufLen, WCHAR, lstrlenA(lpcszPath) + 1, MAX_PATH);
|
|
if (NULL == pszTmp)
|
|
{
|
|
return FALSE; // didn't get the buffer
|
|
}
|
|
MultiByteToWideChar(CP_ACP, 0, lpcszPath, -1, pszTmp, dwBufLen);
|
|
BOOL bReturn = IsPathSharedW(pszTmp, bRefresh);
|
|
FREE_BUFFER(pszTmp);
|
|
|
|
InterlockedDecrement((long*)&g_NonOLEDLLRefs);
|
|
return bReturn;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: SharingDialog
|
|
//
|
|
// Synopsis: This API brings up the "Sharing" dialog. This entrypoint is
|
|
// only used by the FAX team, as far as I know. Note that the
|
|
// paths passed in are ANSI---that's because that's what they
|
|
// were in Win95 when the API was defined.
|
|
//
|
|
// This API, on NT, only works locally. It does not do remote
|
|
// sharing, as Win95 does. Thus, the pszComputerName parameter
|
|
// is ignored.
|
|
//
|
|
// Arguments: hwndParent -- parent window
|
|
// pszComputerName -- a computer name. This is ignored!
|
|
// pszPath -- the path to share.
|
|
//
|
|
// Returns: TRUE if everything went OK, FALSE otherwise
|
|
//
|
|
// History: 5-Oct-95 BruceFo Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL WINAPI
|
|
SharingDialogW(
|
|
HWND hwndParent,
|
|
LPWSTR pszComputerName,
|
|
LPWSTR pszPath
|
|
)
|
|
{
|
|
InterlockedIncrement((long*)&g_NonOLEDLLRefs);
|
|
appDebugOut((DEB_TRACE,"SharingDialogW(%ws)\n", pszPath));
|
|
|
|
// Parameter validation
|
|
if (NULL == pszPath)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (NULL != pszComputerName)
|
|
{
|
|
appDebugOut((DEB_TRACE,
|
|
"SharingDialog() API called with a computer name which will be ignored\n"));
|
|
}
|
|
|
|
// Make sure the DLL is initialized. Note that this loads up the share
|
|
// cache in this address space. Also, the first thing the dialog does
|
|
// is refresh the cache, so we just wasted the work done to create the
|
|
// cache in the init. Oh well...
|
|
OneTimeInit(TRUE);
|
|
|
|
PWSTR pszCopy = NewDup(pszPath);
|
|
if (NULL == pszCopy)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL bReturn = SharingDialogHelp(hwndParent, pszCopy);
|
|
InterlockedDecrement((long*)&g_NonOLEDLLRefs);
|
|
return bReturn;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: SharingDialogA
|
|
//
|
|
// Synopsis: see SharingDialogW
|
|
//
|
|
// Arguments: see SharingDialogW
|
|
//
|
|
// Returns: see SharingDialogW
|
|
//
|
|
// History: 1-Mar-96 BruceFo Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL WINAPI
|
|
SharingDialogA(
|
|
HWND hwndParent,
|
|
LPSTR pszComputerName,
|
|
LPSTR pszPath
|
|
)
|
|
{
|
|
InterlockedIncrement((long*)&g_NonOLEDLLRefs);
|
|
appDebugOut((DEB_TRACE,"SharingDialogA(%s)\n", pszPath));
|
|
|
|
// Parameter validation
|
|
if (NULL == pszPath)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (NULL != pszComputerName)
|
|
{
|
|
appDebugOut((DEB_TRACE,
|
|
"SharingDialog() API called with a computer name which will be ignored\n"));
|
|
}
|
|
|
|
// Make sure the DLL is initialized. Note that this loads up the share
|
|
// cache in this address space. Also, the first thing the dialog does
|
|
// is refresh the cache, so we just wasted the work done to create the
|
|
// cache in the init. Oh well...
|
|
OneTimeInit(TRUE);
|
|
|
|
DWORD dwLen = lstrlenA(pszPath) + 1;
|
|
PWSTR pszUnicodePath = new WCHAR[dwLen];
|
|
if (NULL == pszUnicodePath)
|
|
{
|
|
appDebugOut((DEB_ERROR,"OUT OF MEMORY\n"));
|
|
return FALSE;
|
|
}
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, pszPath, -1, pszUnicodePath, dwLen);
|
|
BOOL bReturn = SharingDialogHelp(hwndParent, pszUnicodePath);
|
|
InterlockedDecrement((long*)&g_NonOLEDLLRefs);
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
static BOOL WINAPI
|
|
SharingDialogHelp(
|
|
HWND hwndParent,
|
|
LPWSTR pszPath // this is 'new' memory that I take ownership of
|
|
)
|
|
{
|
|
CSharingPropertyPage* pPage = new CSharingPropertyPage(pszPath, TRUE);
|
|
if (NULL == pPage)
|
|
{
|
|
delete[] pszPath;
|
|
return FALSE;
|
|
}
|
|
|
|
HRESULT hr = pPage->InitInstance();
|
|
if (FAILED(hr))
|
|
{
|
|
delete pPage;
|
|
return FALSE;
|
|
}
|
|
|
|
PROPSHEETPAGE psp;
|
|
|
|
psp.dwSize = sizeof(psp); // no extra data.
|
|
psp.dwFlags = PSP_USEREFPARENT | PSP_USECALLBACK;
|
|
psp.hInstance = g_hInstance;
|
|
psp.pszTemplate = MAKEINTRESOURCE(IDD_SHARE_PROPERTIES);
|
|
psp.hIcon = NULL;
|
|
psp.pszTitle = NULL;
|
|
psp.pfnDlgProc = CSharingPropertyPage::DlgProcPage;
|
|
psp.lParam = (LPARAM)pPage; // transfer ownership
|
|
psp.pfnCallback = CSharingPropertyPage::PageCallback;
|
|
psp.pcRefParent = &g_NonOLEDLLRefs;
|
|
|
|
INT_PTR ret = DialogBoxParam(
|
|
g_hInstance,
|
|
MAKEINTRESOURCE(IDD_SHARE_PROPERTIES),
|
|
hwndParent,
|
|
CSharingPropertyPage::DlgProcPage,
|
|
(LPARAM)&psp);
|
|
if (-1 == ret)
|
|
{
|
|
appDebugOut((DEB_ERROR,"DialogBoxParam() error, 0x%08lx\n",GetLastError()));
|
|
delete pPage;
|
|
return FALSE;
|
|
}
|
|
|
|
// Now we must simulate a property sheet destroy.
|
|
|
|
CSharingPropertyPage::PageCallback(NULL, PSPCB_RELEASE, &psp);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// APPCOMPAT: there appears to be a bug in the Win95 code where they think
|
|
// they're storing and using "\\machine\share", but it appears they are
|
|
// actually storing and using "machine\share".
|
|
|
|
DWORD
|
|
CopyShareNameToBuffer(
|
|
IN CShareInfo* p,
|
|
IN OUT LPWSTR lpszNameBuf,
|
|
IN DWORD cchNameBufLen
|
|
)
|
|
{
|
|
appAssert(NULL != lpszNameBuf);
|
|
appAssert(0 != cchNameBufLen);
|
|
|
|
WCHAR szLocalComputer[MAX_COMPUTERNAME_LENGTH + 1];
|
|
DWORD nSize = ARRAYLEN(szLocalComputer);
|
|
if (!GetComputerName(szLocalComputer, &nSize))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
/* Two slashes + server name + slash + share name + null terminator. */
|
|
|
|
DWORD computerLen = wcslen(szLocalComputer);
|
|
DWORD shareLen = wcslen(p->GetNetname());
|
|
if (2 + computerLen + 1 + shareLen + 1 <= cchNameBufLen)
|
|
{
|
|
/* Return network resource name as UNC path. */
|
|
|
|
lpszNameBuf[0] = L'\\';
|
|
lpszNameBuf[1] = L'\\';
|
|
wcscpy(lpszNameBuf + 2, szLocalComputer);
|
|
*(lpszNameBuf + 2 + computerLen) = L'\\';
|
|
wcscpy(lpszNameBuf + 2 + computerLen + 1, p->GetNetname());
|
|
return ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
return ERROR_MORE_DATA;
|
|
}
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: GetNetResourceFromLocalPathW
|
|
//
|
|
// Synopsis: Used by shell link tracking code.
|
|
//
|
|
// Arguments: [lpcszPath] Path we're concerned about.
|
|
// [lpszNameBuf] If path is shared, UNC path to share goes here.
|
|
// [cchNameBufLen] length of lpszNameBuf buffer in characters
|
|
// [pdwNetType] net type of local server, e.g., WNNC_NET_LANMAN
|
|
//
|
|
// Returns: TRUE if path is shared and net resource information
|
|
// returned, else FALSE.
|
|
//
|
|
// Notes: *lpszNameBuf and *pwNetType are only valid if TRUE is returned.
|
|
//
|
|
// Example: If c:\documents is shared as MyDocs on machine Scratch, then
|
|
// calling GetNetResourceFromLocalPath(c:\documents, ...) will
|
|
// set lpszNameBuf to \\Scratch\MyDocs.
|
|
//
|
|
// History: 3-Mar-96 BruceFo Created from Win95 sources
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL WINAPI
|
|
GetNetResourceFromLocalPathW(
|
|
IN LPCWSTR lpcszPath,
|
|
IN OUT LPWSTR lpszNameBuf,
|
|
IN DWORD cchNameBufLen,
|
|
OUT PDWORD pdwNetType
|
|
)
|
|
{
|
|
InterlockedIncrement((long*)&g_NonOLEDLLRefs);
|
|
appDebugOut((DEB_TRACE,"GetNetResourceFromLocalPathW(%ws)\n", lpcszPath));
|
|
|
|
// do some parameter validation
|
|
if (NULL == lpcszPath || NULL == lpszNameBuf || NULL == pdwNetType || 0 == cchNameBufLen)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
InterlockedDecrement((long*)&g_NonOLEDLLRefs);
|
|
return FALSE;
|
|
}
|
|
|
|
OneTimeInit();
|
|
|
|
// Parameters seem OK (pointers might still point to bad memory);
|
|
// do the work.
|
|
|
|
CShareInfo* pShareList = new CShareInfo(); // dummy head node
|
|
if (NULL == pShareList)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
InterlockedDecrement((long*)&g_NonOLEDLLRefs);
|
|
return FALSE; // out of memory
|
|
}
|
|
|
|
BOOL bReturn = FALSE;
|
|
DWORD dwLastError;
|
|
DWORD cShares;
|
|
HRESULT hr = g_ShareCache.ConstructList(lpcszPath, pShareList, &cShares);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Now, we have a list of (possibly zero) shares. The user is asking for
|
|
// one of them. Give them the first normal, non-special share. If there
|
|
// doesn't exist a non-special share, then give them a special share.
|
|
|
|
if (cShares > 0)
|
|
{
|
|
BOOL bFoundOne = FALSE;
|
|
CShareInfo* p;
|
|
|
|
for (p = (CShareInfo*) pShareList->Next();
|
|
p != pShareList;
|
|
p = (CShareInfo*) p->Next())
|
|
{
|
|
if (p->GetType() == STYPE_DISKTREE)
|
|
{
|
|
// found a share for this one.
|
|
bFoundOne = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!bFoundOne)
|
|
{
|
|
for (p = (CShareInfo*) pShareList->Next();
|
|
p != pShareList;
|
|
p = (CShareInfo*) p->Next())
|
|
{
|
|
if (p->GetType() == (STYPE_SPECIAL | STYPE_DISKTREE))
|
|
{
|
|
bFoundOne = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bFoundOne)
|
|
{
|
|
dwLastError = CopyShareNameToBuffer(p, lpszNameBuf, cchNameBufLen);
|
|
if (ERROR_SUCCESS == dwLastError)
|
|
{
|
|
bReturn = TRUE;
|
|
*pdwNetType = WNNC_NET_LANMAN; // we only support LanMan
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// nothing found!
|
|
dwLastError = ERROR_BAD_NET_NAME;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwLastError = ERROR_BAD_NET_NAME;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwLastError = ERROR_OUTOFMEMORY;
|
|
}
|
|
|
|
DeleteShareInfoList(pShareList, TRUE);
|
|
|
|
if (!bReturn)
|
|
{
|
|
SetLastError(dwLastError);
|
|
}
|
|
|
|
InterlockedDecrement((long*)&g_NonOLEDLLRefs);
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
BOOL WINAPI
|
|
GetNetResourceFromLocalPathA(
|
|
IN LPCSTR lpcszPath,
|
|
IN OUT LPSTR lpszNameBuf,
|
|
IN DWORD cchNameBufLen,
|
|
OUT PDWORD pdwNetType
|
|
)
|
|
{
|
|
InterlockedIncrement((long*)&g_NonOLEDLLRefs);
|
|
appDebugOut((DEB_TRACE,"GetNetResourceFromLocalPathA(%s)\n", lpcszPath));
|
|
BOOL bReturn = FALSE;
|
|
LPWSTR pszPathTmp, pszNameTmp;
|
|
DWORD dwPathBufLen, dwNameBufLen;
|
|
GET_BUFFER(pszPathTmp, dwPathBufLen, WCHAR, lstrlenA(lpcszPath) + 1, MAX_PATH);
|
|
if (NULL != pszPathTmp)
|
|
{
|
|
MultiByteToWideChar(CP_ACP, 0, lpcszPath, -1, pszPathTmp, dwPathBufLen);
|
|
|
|
GET_BUFFER(pszNameTmp, dwNameBufLen, WCHAR, cchNameBufLen, MAX_PATH);
|
|
if (NULL != pszNameTmp)
|
|
{
|
|
// got the buffers, now party...
|
|
bReturn = GetNetResourceFromLocalPathW(pszPathTmp, pszNameTmp, cchNameBufLen, pdwNetType);
|
|
if (bReturn)
|
|
{
|
|
// now convert the return string back
|
|
WideCharToMultiByte(CP_ACP, 0,
|
|
pszNameTmp, -1,
|
|
lpszNameBuf, cchNameBufLen,
|
|
NULL, NULL);
|
|
}
|
|
|
|
FREE_BUFFER(pszNameTmp);
|
|
}
|
|
else
|
|
{
|
|
// didn't get the buffer
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
}
|
|
|
|
FREE_BUFFER(pszPathTmp);
|
|
}
|
|
else
|
|
{
|
|
// didn't get the buffer
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
}
|
|
|
|
InterlockedDecrement((long*)&g_NonOLEDLLRefs);
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: GetLocalPathFromNetResourceW
|
|
//
|
|
// Synopsis: Used by shell link tracking code.
|
|
//
|
|
// Arguments: [lpcszName] A UNC path we're concerned about.
|
|
// [dwNetType] net type of local server, e.g., WNNC_NET_LANMAN
|
|
// [lpszLocalPathBuf] Buffer to place local path of UNC path
|
|
// [cchLocalPathBufLen] length of lpszLocalPathBuf buffer in
|
|
// characters
|
|
// [pbIsLocal] Set to TRUE if lpcszName points to a local
|
|
// resource.
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes: *lpszLocalPathBuf and *pbIsLocal are only valid if
|
|
// TRUE is returned.
|
|
//
|
|
// Example: If c:\documents is shared as MyDocs on machine Scratch, then
|
|
// calling GetLocalPathFromNetResource(\\Scratch\MyDocs, ...) will
|
|
// set lpszLocalPathBuf to c:\documents.
|
|
//
|
|
// History: 3-Mar-96 BruceFo Created from Win95 sources
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL WINAPI
|
|
GetLocalPathFromNetResourceW(
|
|
IN LPCWSTR lpcszName,
|
|
IN DWORD dwNetType,
|
|
IN OUT LPWSTR lpszLocalPathBuf,
|
|
IN DWORD cchLocalPathBufLen,
|
|
OUT PBOOL pbIsLocal
|
|
)
|
|
{
|
|
InterlockedIncrement((long*)&g_NonOLEDLLRefs);
|
|
appDebugOut((DEB_TRACE,"GetLocalPathFromNetResourceW(%ws)\n", lpcszName));
|
|
OneTimeInit();
|
|
|
|
BOOL bReturn = FALSE;
|
|
DWORD dwLastError;
|
|
|
|
*pbIsLocal = FALSE;
|
|
|
|
if (g_fSharingEnabled)
|
|
{
|
|
if (0 != dwNetType && HIWORD(dwNetType) == HIWORD(WNNC_NET_LANMAN))
|
|
{
|
|
/* Is the network resource name a UNC path on this machine? */
|
|
|
|
WCHAR szLocalComputer[MAX_COMPUTERNAME_LENGTH + 1];
|
|
DWORD nSize = ARRAYLEN(szLocalComputer);
|
|
if (!GetComputerName(szLocalComputer, &nSize))
|
|
{
|
|
dwLastError = GetLastError();
|
|
}
|
|
else
|
|
{
|
|
dwLastError = ERROR_BAD_NET_NAME;
|
|
|
|
DWORD dwLocalComputerLen = wcslen(szLocalComputer);
|
|
if ( lpcszName[0] == L'\\'
|
|
&& lpcszName[1] == L'\\'
|
|
&& (0 == _wcsnicmp(lpcszName + 2, szLocalComputer, dwLocalComputerLen))
|
|
)
|
|
{
|
|
LPCWSTR lpcszSep = &(lpcszName[2 + dwLocalComputerLen]);
|
|
if (*lpcszSep == L'\\')
|
|
{
|
|
*pbIsLocal = TRUE;
|
|
|
|
WCHAR szLocalPath[MAX_PATH];
|
|
if (g_ShareCache.IsExistingShare(lpcszSep + 1, NULL, szLocalPath))
|
|
{
|
|
if (wcslen(szLocalPath) < cchLocalPathBufLen)
|
|
{
|
|
wcscpy(lpszLocalPathBuf, szLocalPath);
|
|
dwLastError = ERROR_SUCCESS;
|
|
bReturn = TRUE;
|
|
}
|
|
else
|
|
{
|
|
dwLastError = ERROR_MORE_DATA;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwLastError = ERROR_BAD_PROVIDER;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
appDebugOut((DEB_TRACE,"GetLocalPathFromNetResourceW: sharing not enabled\n"));
|
|
dwLastError = ERROR_BAD_NET_NAME;
|
|
}
|
|
|
|
if (!bReturn)
|
|
{
|
|
SetLastError(dwLastError);
|
|
}
|
|
|
|
InterlockedDecrement((long*)&g_NonOLEDLLRefs);
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
BOOL WINAPI
|
|
GetLocalPathFromNetResourceA(
|
|
IN LPCSTR lpcszName,
|
|
IN DWORD dwNetType,
|
|
IN OUT LPSTR lpszLocalPathBuf,
|
|
IN DWORD cchLocalPathBufLen,
|
|
OUT PBOOL pbIsLocal
|
|
)
|
|
{
|
|
InterlockedIncrement((long*)&g_NonOLEDLLRefs);
|
|
appDebugOut((DEB_TRACE,"GetLocalPathFromNetResourceA(%s)\n", lpcszName));
|
|
|
|
BOOL bReturn = FALSE;
|
|
LPWSTR pszLocalPathTmp, pszNameTmp;
|
|
DWORD dwPathBufLen, dwNameBufLen;
|
|
GET_BUFFER(pszLocalPathTmp, dwPathBufLen, WCHAR, cchLocalPathBufLen, MAX_PATH);
|
|
if (NULL != pszLocalPathTmp)
|
|
{
|
|
GET_BUFFER(pszNameTmp, dwNameBufLen, WCHAR, lstrlenA(lpszLocalPathBuf) + 1, MAX_PATH);
|
|
if (NULL != pszNameTmp)
|
|
{
|
|
MultiByteToWideChar(CP_ACP, 0, lpcszName, -1, pszNameTmp, dwNameBufLen);
|
|
|
|
// got the buffers, now party...
|
|
bReturn = GetLocalPathFromNetResourceW(pszNameTmp, dwNetType, pszLocalPathTmp, cchLocalPathBufLen, pbIsLocal);
|
|
if (bReturn)
|
|
{
|
|
// now convert the return string back
|
|
WideCharToMultiByte(CP_ACP, 0,
|
|
pszLocalPathTmp, -1,
|
|
lpszLocalPathBuf, cchLocalPathBufLen,
|
|
NULL, NULL);
|
|
}
|
|
|
|
FREE_BUFFER(pszNameTmp);
|
|
}
|
|
else
|
|
{
|
|
// didn't get the buffer
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
}
|
|
|
|
FREE_BUFFER(pszLocalPathTmp);
|
|
}
|
|
else
|
|
{
|
|
// didn't get the buffer
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
}
|
|
|
|
InterlockedDecrement((long*)&g_NonOLEDLLRefs);
|
|
return bReturn;
|
|
}
|
|
|
|
STDAPI CanShareFolderW(LPCWSTR pszPath)
|
|
{
|
|
InterlockedIncrement((long*)&g_NonOLEDLLRefs);
|
|
appDebugOut((DEB_TRACE,"CanShareFolderW(%s)\n", pszPath));
|
|
OneTimeInit();
|
|
|
|
HRESULT hr = S_FALSE;
|
|
|
|
if (g_fSharingEnabled || IsSimpleUI())
|
|
{
|
|
if ( (pszPath[0] >= L'A' && pszPath[0] <= L'Z') && pszPath[1] == L':')
|
|
{
|
|
WCHAR szRoot[4];
|
|
|
|
szRoot[0] = pszPath[0];
|
|
szRoot[1] = TEXT(':');
|
|
szRoot[2] = TEXT('\\');
|
|
szRoot[3] = 0;
|
|
|
|
UINT uType = GetDriveType(szRoot);
|
|
|
|
switch (uType)
|
|
{
|
|
case DRIVE_UNKNOWN:
|
|
case DRIVE_NO_ROOT_DIR:
|
|
case DRIVE_REMOTE:
|
|
hr = S_FALSE;
|
|
break;
|
|
|
|
case DRIVE_FIXED:
|
|
case DRIVE_REMOVABLE:
|
|
{
|
|
WCHAR szDesktopIni[MAX_PATH];
|
|
PathCombine(szDesktopIni, pszPath, TEXT("desktop.ini"));
|
|
hr = GetPrivateProfileInt(TEXT(".ShellClassInfo"), TEXT("Sharing"), TRUE, szDesktopIni) ? S_OK : S_FALSE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// NTRAID#NTBUG9-353119-2001/04/10-jeffreys
|
|
//
|
|
// We need to call PathIsDirectory to prevent the "Share this
|
|
// folder" task from appearing in the webview pane of CAB and
|
|
// ZIP folders. (NTBUG9 #319149 and 319153)
|
|
//
|
|
// However, PathIsDirectory fails with ERROR_NOT_READY on an
|
|
// empty CD or removable drive, which is a case we want to allow
|
|
// or the Sharing page will not show. (NTBUG9 #353119)
|
|
//
|
|
if (S_OK == hr && !PathIsDirectory(pszPath))
|
|
{
|
|
hr = S_FALSE;
|
|
|
|
if (GetLastError() == ERROR_NOT_READY &&
|
|
(DRIVE_CDROM == uType || DRIVE_REMOVABLE == uType) &&
|
|
PathIsRootW(pszPath))
|
|
{
|
|
// Ok to share an empty CD or removable drive
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
InterlockedDecrement((long*)&g_NonOLEDLLRefs);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDAPI ShowShareFolderUIW(HWND hwndParent, LPCWSTR pszPath)
|
|
{
|
|
InterlockedIncrement((long*)&g_NonOLEDLLRefs);
|
|
appDebugOut((DEB_TRACE,"ShowShareFolderUIW(%s)\n", pszPath));
|
|
|
|
TCHAR szShare[50];
|
|
LoadString(g_hInstance, IDS_MSGTITLE, szShare, ARRAYLEN(szShare));
|
|
SHObjectProperties(hwndParent, SHOP_FILEPATH, pszPath, szShare);
|
|
|
|
InterlockedDecrement((long*)&g_NonOLEDLLRefs);
|
|
|
|
return S_OK;
|
|
}
|