|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1994.
//
// File: myutil.cxx
//
// Contents: Helper APIs for Sharing Tool
//
// History: 6-Jun-93 WilliamW Created
//
//----------------------------------------------------------------------------
#include "headers.hxx"
#pragma hdrstop
////////////////////////////////////////////////////////////////////////////
//+-------------------------------------------------------------------------
//
// Member: MyGetLastComponent, public
//
// Synopsis: Parse a string to a (prefix, last-component) pair. Any
// trailing text after L'.' will be ignored
//
// History: 07-May-93 WilliamW Created
//
// Notes: pszPrefix and pszLastComponent should be pre-allocated
//
//--------------------------------------------------------------------------
VOID MyGetLastComponent( IN PWSTR pszStr, OUT PWSTR pszPrefix, OUT PWSTR pszLastComponent ) { PWSTR pszTmp = NULL; PWSTR pszTmpLast = NULL;
//
// Manufacture the prefix part by replacing L'\\' with L'\0'
//
wcscpy(pszPrefix, pszStr);
pszTmp = wcsrchr(pszPrefix, L'\\'); if (pszTmp != NULL) { *pszTmp = L'\0';
//
// Extract the last component. The L'.' part will be replaced
// by a L'\0'
//
pszTmpLast = pszTmp + 1; pszTmp = wcsrchr(pszTmpLast, L'.'); if (pszTmp != NULL) { //
// Replace with a L'\0' character
//
*pszTmp = L'\0'; } wcscpy(pszLastComponent, pszTmpLast); } else { *pszPrefix = L'\0'; wcscpy(pszLastComponent, pszStr); } }
//+-------------------------------------------------------------------------
//
// Member: MyFindLastComponent, public
//
// Synopsis: Parse a string to find the last component. This is different
// from MyGetLastComponent as it doesn't copy any data, but just
// looks for the last backslash and points one after it.
//
// History: 21-Nov-94 BruceFo
//
//--------------------------------------------------------------------------
PWSTR MyFindLastComponent( IN const WCHAR* pszStr ) { PWSTR pszTmp = wcsrchr(pszStr, L'\\'); if (pszTmp != NULL) { return pszTmp + 1; } else { return (PWSTR)pszStr; // cast away const
} }
//+-------------------------------------------------------------------------
//
// Member: MyGetNextComponent(), public
//
// Synopsis: Parse a string to a (next-components, remaing-components)
// pair. Any
//
// History: 07-May-93 WilliamW Created
//
// Notes: pszNextComponent and pszRemaining should be pre-allocated.
//
//--------------------------------------------------------------------------
VOID MyGetNextComponent( IN PWSTR pszStr, OUT PWSTR pszNextComponent, OUT PWSTR pszRemaining ) { PWSTR pszTmp = NULL;
if (*pszStr == L'\0') { *pszNextComponent = *pszRemaining = L'\0'; return; }
#if DBG == 1
if (*pszStr == L'\\') { appDebugOut((DEB_IERROR, "WARNING: MyGetNextComponent takes a relative path as its first argument\n")); } #endif // DBG == 1
//
// Manufacture the next component part by replacing L'\\' with L'\0'
//
pszTmp = wcschr(pszStr, L'\\'); if (pszTmp != NULL) { ULONG cchNextComponent = (ULONG)(pszTmp - pszStr); wcsncpy(pszNextComponent, pszStr, cchNextComponent); pszNextComponent[cchNextComponent] = L'\0';
//
// Handle the remaining component.
//
wcscpy(pszRemaining, pszTmp + 1); } else { //
// No remaining part, this is the last component
//
*pszRemaining = L'\0';
wcscpy(pszNextComponent, pszStr); } }
//+-------------------------------------------------------------------------
//
// Method: MyStrStr
//
// Synopsis: A case insensitive version of wcsstr (i.e. strstr)
//
//--------------------------------------------------------------------------
PWSTR MyStrStr( IN PWSTR pszInStr, IN PWSTR pszInSubStr ) { if ( pszInStr == NULL || pszInSubStr == NULL || *pszInStr == L'\0' || *pszInSubStr == L'\0') { return NULL; }
INT iSubStrLen = wcslen(pszInSubStr); INT iStrLen = wcslen(pszInStr);
PWSTR pszHeadInStr = pszInStr; PWSTR pszTailInStr = pszInStr + iSubStrLen;
PWSTR pszEndInStr = pszInStr + iStrLen;
while (pszTailInStr <= pszEndInStr) { if (0 != _wcsnicmp(pszHeadInStr, pszInSubStr, iSubStrLen)) { return pszHeadInStr; }
pszHeadInStr++; pszTailInStr++; }
return NULL; }
//+-------------------------------------------------------------------------
//
// Method: MyFindPostfix
//
// Synopsis: Match the prefix with the string. If the string doesn't have
// the prefix, return a pointer to the string itself. If it does,
// then check to see if the character after the prefix is a
// backslash. If it is, return a pointer to the character
// following the backslash. Otherwise, return a pointer to the
// character immediately after the prefix.
//
// Examples:
// string prefix return
// \foo\bar\baz \bad \foo\bar\baz
// \foo\bar\baz \foo\bar baz
// \foo\bar\baz \f oo\bar\baz
//
//--------------------------------------------------------------------------
PWSTR MyFindPostfix( IN PWSTR pszString, IN PWSTR pszPrefix ) { UINT cchPrefixLen = wcslen(pszPrefix); if (0 == _wcsnicmp(pszString, pszPrefix, cchPrefixLen)) { PWSTR pszReturn = pszString + cchPrefixLen;
if (*pszReturn == L'\\') { //
// skip past the leading backslash.
//
++pszReturn; }
return pszReturn; } else { // prefix didn't match, return argument string
// appDebugOut((DEB_ITRACE,
// "No postfix of ('%ws', '%ws')\n",
// pszString,
// pszPrefix));
return pszString; } }
//+-------------------------------------------------------------------------
//
// Function: MyFormatMessageText
//
// Synopsis: Given a resource IDs, load strings from given instance
// and format the string into a buffer
//
// History: 11-Aug-93 WilliamW Created.
//
//--------------------------------------------------------------------------
VOID MyFormatMessageText( IN HRESULT dwMsgId, IN PWSTR pszBuffer, IN DWORD dwBufferSize, IN va_list * parglist ) { //
// get message from system or app msg file.
//
DWORD dwReturn = FormatMessage( (dwMsgId >= MSG_FIRST_MESSAGE) ? FORMAT_MESSAGE_FROM_HMODULE : FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMsgId, LANG_USER_DEFAULT, pszBuffer, dwBufferSize, parglist);
if (0 == dwReturn) // couldn't find message
{ appDebugOut((DEB_IERROR, "Formatmessage failed = 0x%08lx\n", GetLastError()));
WCHAR szText[200]; LoadString(g_hInstance, (dwMsgId >= MSG_FIRST_MESSAGE) ? IDS_APP_MSG_NOT_FOUND : IDS_SYS_MSG_NOT_FOUND, szText, ARRAYLEN(szText));
wsprintf(pszBuffer,szText,dwMsgId); } }
//+-------------------------------------------------------------------------
//
// Function: MyFormatMessage
//
// Synopsis: Given a resource IDs, load strings from given instance
// and format the string into a buffer
//
// History: 11-Aug-93 WilliamW Created.
//
//--------------------------------------------------------------------------
VOID MyFormatMessage( IN HRESULT dwMsgId, IN PWSTR pszBuffer, IN DWORD dwBufferSize, ... ) { va_list arglist;
va_start(arglist, dwBufferSize); MyFormatMessageText(dwMsgId, pszBuffer, dwBufferSize, &arglist); va_end(arglist); }
//+---------------------------------------------------------------------------
//
// Function: NewDup
//
// Synopsis: Duplicate a string using '::new'
//
// Arguments:
//
// Returns:
//
// History: 28-Dec-94 BruceFo Created
//
//----------------------------------------------------------------------------
PWSTR NewDup( IN const WCHAR* psz ) { if (NULL == psz) { return NULL; }
PWSTR pszRet = new WCHAR[wcslen(psz) + 1]; if (NULL == pszRet) { appDebugOut((DEB_ERROR,"OUT OF MEMORY\n")); return NULL; }
wcscpy(pszRet, psz); return pszRet; }
//+---------------------------------------------------------------------------
//
// Function: wcsistr
//
// Synopsis: Same as wcsstr (find string in string), but case-insensitive
//
// Arguments:
//
// Returns:
//
// History: 2-Feb-95 BruceFo Created
//
//----------------------------------------------------------------------------
wchar_t* wcsistr( const wchar_t* string1, const wchar_t* string2 ) { if ((NULL == string2) || (NULL == string1)) { // do whatever wcsstr would do
return wcsstr(string1, string2); }
wchar_t* s1dup = NewDup(string1); wchar_t* s2dup = NewDup(string2);
wchar_t* ret = NULL;
if (NULL != s1dup && NULL != s2dup) { _wcslwr(s1dup); // lower case everything to make case-insensitive
_wcslwr(s2dup); ret = wcsstr(s1dup, s2dup); }
delete[] s1dup; delete[] s2dup; return ret; }
//+---------------------------------------------------------------------------
//
// Function: GetResourceString
//
// Synopsis: Load a resource string, are return a "new"ed copy
//
// Arguments: [dwId] -- a resource string ID
//
// Returns: new memory copy of a string
//
// History: 5-Apr-95 BruceFo Created
//
//----------------------------------------------------------------------------
PWSTR GetResourceString( IN DWORD dwId ) { WCHAR sz[50]; if (0 == LoadString(g_hInstance, dwId, sz, ARRAYLEN(sz))) { return NULL; } else { return NewDup(sz); } }
//+-------------------------------------------------------------------------
//
// Function: IsDfsRoot
//
// Synopsis: Determine if the path passed in is a Dfs root, in form only.
// Namely, does it look like "\\machine-or-domain\share"?
//
// Arguments: none
//
// Returns: nothing
//
// History: 18-Apr-96 BruceFo Created
//
//--------------------------------------------------------------------------
BOOL IsDfsRoot( IN LPWSTR pszRoot ) { if (NULL != pszRoot && pszRoot[0] == L'\\' && pszRoot[1] == L'\\' && pszRoot[2] != L'\\' // might be null
) { LPWSTR pszTmp = wcschr(pszRoot + 2, L'\\'); if (pszTmp != NULL) { if (pszTmp[1] != L'\0' && pszTmp[1] != L'\\' ) { // ok, we've got "\\xxx\y...."
// Now make sure it doesn't have a fourth backslash
pszTmp = wcschr(pszTmp + 2, L'\\'); if (pszTmp == NULL) { return TRUE; } } } }
return FALSE; }
//+-------------------------------------------------------------------------
//
// Function: IsDfsShare
//
// Synopsis: Determine if the given share on the given server is a Dfs
// share. This actually contacts the machine.
//
// Arguments: none
//
// Returns: nothing
//
// History: 18-Apr-96 BruceFo Created
//
//--------------------------------------------------------------------------
DWORD IsDfsShare( IN LPWSTR pszServer, IN LPWSTR pszShare, OUT BOOL* pfIsDfs ) { PSHARE_INFO_1005 pshi1005; NET_API_STATUS ret = NetShareGetInfo(pszServer, pszShare, 1005, (LPBYTE*)&pshi1005); if (NERR_Success == ret) { if (pshi1005->shi1005_flags & SHI1005_FLAGS_DFS) { *pfIsDfs = TRUE; } else { appDebugOut((DEB_ITRACE, "%ws not a Dfs share\n", pszShare)); }
NetApiBufferFree(pshi1005); } else { // This could be an access denied.
appDebugOut((DEB_ERROR, "NetShareGetInfo(NULL, %ws...) failed, 0x%08lx\n", pszShare, ret)); }
return ret; }
//+-------------------------------------------------------------------------
//
// Member: FindDfsRoot, public
//
// Synopsis: Parse a string to find the Dfs root. Returns a pointer to
//
// History: 22-Apr-96 BruceFo
//
//--------------------------------------------------------------------------
BOOL FindDfsRoot( IN PWSTR pszDfsPath, OUT PWSTR pszDfsRoot ) { PWSTR pszTmp; if (NULL != pszDfsPath && pszDfsPath[0] == L'\\' && pszDfsPath[1] == L'\\' && pszDfsPath[2] != L'\\' && pszDfsPath[2] != L'\0' && (NULL != (pszTmp = wcschr(pszDfsPath + 3, L'\\'))) && pszTmp[1] != L'\\' && pszTmp[1] != L'\0' ) { pszTmp = wcschr(pszTmp + 2, L'\\');
if (NULL != pszTmp) { // the thing passed in was of the form "\\xxx\yyy\..."
int len = (int)(pszTmp - pszDfsPath); wcsncpy(pszDfsRoot, pszDfsPath, len); pszDfsRoot[len] = L'\0'; } else { // the thing passed in was of the form "\\xxx\yyy"
wcscpy(pszDfsRoot, pszDfsPath); }
appDebugOut((DEB_IERROR, "Dfs root of %ws is %ws\n", pszDfsPath, pszDfsRoot));
return TRUE; } else { return FALSE; } }
#define MAX_MESSAGE_BUF 8192
#define MAX_ANSI_MESSAGE_BUF (MAX_MESSAGE_BUF * 3)
WCHAR szMsgBuf[MAX_MESSAGE_BUF]; CHAR szAnsiBuf[MAX_ANSI_MESSAGE_BUF]; VOID StatusMessage( IN HRESULT hr, ... ) { va_list arglist; va_start(arglist, hr); ULONG written;
MyFormatMessageText(hr, szMsgBuf, ARRAYLEN(szMsgBuf), &arglist); written = WideCharToMultiByte(CP_OEMCP, 0, szMsgBuf, wcslen(szMsgBuf), szAnsiBuf, MAX_ANSI_MESSAGE_BUF, NULL, NULL); WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), szAnsiBuf, written, &written, NULL);
va_end(arglist); }
VOID ErrorMessage( IN HRESULT hr, ... ) { va_list arglist; va_start(arglist, hr); ULONG written;
MyFormatMessageText(hr, szMsgBuf, ARRAYLEN(szMsgBuf), &arglist); written = WideCharToMultiByte(CP_OEMCP, 0, szMsgBuf, wcslen(szMsgBuf), szAnsiBuf, MAX_ANSI_MESSAGE_BUF, NULL, NULL); WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), szAnsiBuf, written, &written, NULL);
va_end(arglist); exit(1); }
VOID DfsErrorMessage( IN NET_API_STATUS status ) { ULONG written;
MyFormatMessage(MSG_ERROR, szMsgBuf, ARRAYLEN(szMsgBuf), status); written = WideCharToMultiByte(CP_OEMCP, 0, szMsgBuf, wcslen(szMsgBuf), szAnsiBuf, MAX_ANSI_MESSAGE_BUF, NULL, NULL); WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), szAnsiBuf, written, &written, NULL);
PWSTR pszDll = L"netmsg.dll";
HINSTANCE hinst = LoadLibrary(pszDll); if (NULL == hinst) { MyFormatMessage(MSG_NO_MESSAGES, szMsgBuf, ARRAYLEN(szMsgBuf), pszDll); } else { DWORD dwReturn = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, hinst, status, LANG_USER_DEFAULT, szMsgBuf, ARRAYLEN(szMsgBuf), NULL); FreeLibrary(hinst);
if (0 == dwReturn) // couldn't find message
{ // try system messages
dwReturn = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, status, LANG_USER_DEFAULT, szMsgBuf, ARRAYLEN(szMsgBuf), NULL); if (0 == dwReturn) // couldn't find message
{ MyFormatMessage(MSG_ERROR_UNKNOWN, szMsgBuf, ARRAYLEN(szMsgBuf)); } } } written = WideCharToMultiByte(CP_OEMCP, 0, szMsgBuf, wcslen(szMsgBuf), szAnsiBuf, MAX_ANSI_MESSAGE_BUF, NULL, NULL); WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), szAnsiBuf, written, &written, NULL);
exit(1); }
VOID Usage( VOID ) { ErrorMessage(MSG_USAGE); }
|