|
|
//
// shint.cpp: client shell utitilies
// internal functions
//
#include "stdafx.h"
#define TRC_GROUP TRC_GROUP_UI
#define TRC_FILE "shint.cpp"
#include <atrcapi.h>
#include "sh.h"
#include "rmigrate.h"
//
// Fix union names, because some headers redifine this
// and break STRRET to str field access
//
#undef DUMMYUNIONNAME
#define NONAMELESSUNION
#define CLXSERVER TEXT("CLXSERVER")
#define CLXCMDLINE TEXT("CLXCMDLINE")
#define FULLSCREEN TEXT("FULLSCREEN")
#define SWITCH_EDIT TEXT("EDIT")
#define SWITCH_MIGRATE TEXT("MIGRATE")
#define SWITCH_CONSOLE TEXT("CONSOLE")
#ifdef NONAMELESSUNION
#define NAMELESS_MEMBER(member) DUMMYUNIONNAME.##member
#else
#define NAMELESS_MEMBER(member) member
#endif
#define STRRET_OLESTR STRRET_WSTR // same as STRRET_WSTR
#define STRRET_OFFPTR(pidl,lpstrret) \
((LPSTR)((LPBYTE)(pidl)+(lpstrret)->NAMELESS_MEMBER(uOffset)))
/****************************************************************************/ /* Name: SHValidateParsedCmdParam */ /* */ /* Purpose: validates settings in _SH that were read from the cmd line */ /* */ /* Returns: Nothing */ /* */ /* Params: IN - lpszCmdParam */ /* */ /****************************************************************************/ DCBOOL CSH::SHValidateParsedCmdParam() { DC_BEGIN_FN("SHValidateParsedCmdParam"); //
//["<session>"] [-v:<server>] [-f[ullscreen]] [-w[idth]:<wd> -h[eight]:<ht>]
//
//
// if one of width/height is specified but not the other..
// then fill with defaults
//
if (_SH.commandLineHeight != _SH.commandLineWidth) { if (!_SH.commandLineHeight) { _SH.commandLineHeight = DEFAULT_DESKTOP_HEIGHT; } if (!_SH.commandLineWidth) { _SH.commandLineWidth = DEFAULT_DESKTOP_WIDTH; } }
//
// clamp to min max sizes. 0 means we are not set
//
if (_SH.commandLineHeight != 0) { if (_SH.commandLineHeight < MIN_DESKTOP_HEIGHT) { _SH.commandLineHeight = MIN_DESKTOP_HEIGHT; } else if (_SH.commandLineHeight > MAX_DESKTOP_HEIGHT) { _SH.commandLineHeight = MAX_DESKTOP_HEIGHT; } } if (_SH.commandLineWidth != 0) { if (_SH.commandLineWidth < MIN_DESKTOP_WIDTH) { _SH.commandLineWidth = MIN_DESKTOP_WIDTH; } else if (_SH.commandLineWidth > MAX_DESKTOP_WIDTH) { _SH.commandLineWidth = MAX_DESKTOP_WIDTH; } }
DC_END_FN(); return TRUE; }
//*************************************************************
//
// CLX_SkipWhite()
//
// Purpose: Skips whitespace characters
//
// Parameters: IN [lpszCmdParam] - Ptr to string
//
// Return: Ptr string past whitespace
//
// History: 09-30-97 BrianTa Created
//
//*************************************************************
LPTSTR CLX_SkipWhite(IN LPTSTR lpszCmdParam) { while (*lpszCmdParam) { if (*lpszCmdParam != ' ') break;
lpszCmdParam++; }
return(lpszCmdParam); }
//*************************************************************
//
// CLX_SkipNonWhite()
//
// Purpose: Skips non-whitespace characters
//
// Parameters: IN [lpszCmdParam] - Ptr to string
//
// Return: Ptr string past non-whitespace
//
// History: 09-30-97 BrianTa Created
//
//*************************************************************
LPTSTR CLX_SkipNonWhite(LPTSTR lpszCmdParam) { char Delim;
Delim = ' ';
if (*lpszCmdParam == '"') { Delim = '"'; lpszCmdParam++; }
while (*lpszCmdParam) { if (*lpszCmdParam == Delim) break;
lpszCmdParam++; }
if (*lpszCmdParam == Delim) lpszCmdParam++;
return(lpszCmdParam); }
//*************************************************************
//
// CLX_GetSwitch_CLXSERVER()
//
// Purpose: Processes /CLXSERVER cmdline switch
//
// Parameters: IN [lpszCmdParam] - Ptr to cmdline
//
// Return: Number of characters consumed
//
// History: 09-30-97 BrianTa Created
//
//*************************************************************
UINT CLX_GetSwitch_CLXSERVER(IN LPTSTR lpszCmdParam) { DC_BEGIN_FN("CLX_GetSwitch_CLXSERVER");
int len; LPTSTR pszEnd; LPTSTR pszStart;
pszStart = CLX_SkipWhite(lpszCmdParam);
TRC_ASSERT(*pszStart == _T('='), (TB,_T("Invalid /clxserver syntax - expected '='\n"))); pszStart++;
pszStart = CLX_SkipWhite(pszStart); pszEnd = CLX_SkipNonWhite(pszStart);
len = (INT) (pszEnd - pszStart);
DC_END_FN(); return(UINT) (pszEnd - lpszCmdParam); }
//*************************************************************
//
// CLX_GetSwitch_CLXCMDLINE()
//
// Purpose: Processes /CLXCMDLINE cmdline switch
//
// Parameters: IN [lpszCmdParam] - Ptr to cmdline
//
// Return: Number of characters consumed
//
// History: 09-30-97 BrianTa Created
//
//*************************************************************
UINT CSH::CLX_GetSwitch_CLXCMDLINE(IN LPTSTR lpszCmdParam) { int len; LPTSTR pszEnd; LPTSTR pszStart; DC_BEGIN_FN("CLX_GetSwitch_CLXCMDLINE");
pszStart = CLX_SkipWhite(lpszCmdParam);
TRC_ASSERT(*pszStart == _T('='), (TB,_T("Invalid /clxserver syntax - expected '='\n")));
pszStart++;
pszStart = CLX_SkipWhite(pszStart); pszEnd = CLX_SkipNonWhite(pszStart);
len = (INT) (pszEnd - pszStart);
if (len > 0) { memmove(_SH.szCLXCmdLine, pszStart, len*sizeof(TCHAR)); _SH.szCLXCmdLine[len] = 0; }
DC_END_FN(); return(UINT) (pszEnd - lpszCmdParam); }
/****************************************************************************/ /* Name: SHGetSwitch */ /* */ /* Purpose: Retrieves cmdline switches */ /* */ /* Returns: Nothing */ /* */ /* Params: IN - lpszCmdParam */ /* */ /****************************************************************************/ LPTSTR CSH::SHGetSwitch(LPTSTR lpszCmdParam) { DCINT i; DCTCHAR szParam[100];
DC_BEGIN_FN("SHGetSwitch");
/************************************************************************/ /* Retrieve the switch (case insensitive) */ /************************************************************************/ i=0;
while (*lpszCmdParam) { if (*lpszCmdParam == _T(' ') || *lpszCmdParam == _T('=') || *lpszCmdParam == _T(':')) break;
if (i < sizeof(szParam) / sizeof(DCTCHAR) - 1) { #ifdef UNICODE
szParam[i] = (DCTCHAR) towupper(*lpszCmdParam); #else // UNICODE
szParam[i] = (DCTCHAR) toupper(*lpszCmdParam); #endif // UNICODE
i++; }
lpszCmdParam++; }
szParam[i] = 0;
#ifndef OS_WINCE
// Are we seeing the "/f" from /F[ullscreen]
if (szParam[0] == _T('F')) { _SH.fCommandStartFullScreen = TRUE; }
// Are we seeing the "/W" from /w[idth]
else if (szParam[0] == _T('W')) { lpszCmdParam = SHGetCmdLineInt(lpszCmdParam, &_SH.commandLineWidth); }
// Are we seeing the "/H" from /h[eight]
else if (szParam[0] == _T('H')) { lpszCmdParam = SHGetCmdLineInt(lpszCmdParam, &_SH.commandLineHeight); }
// Are we seeing the "/V" for server
else
#endif
if (szParam[0] == _T('V')) { lpszCmdParam = SHGetServer(lpszCmdParam); }
// Are we seeing the "/S"
else if (memcmp(szParam, "S", i) == 0) { lpszCmdParam = SHGetSession(lpszCmdParam); }
// Are we seeing the "/C"
else if (memcmp(szParam, "C", i) == 0) { lpszCmdParam = SHGetCacheToClear(lpszCmdParam); }
// Are we seeing the "/CLXCMDLINE=xyzzy"
else if (memcmp(szParam, CLXCMDLINE, i) == 0) { lpszCmdParam += CLX_GetSwitch_CLXCMDLINE(lpszCmdParam); }
else if (memcmp(szParam, FULLSCREEN, i) == 0) { lpszCmdParam += SIZECHAR(FULLSCREEN); }
else if (memcmp(szParam, SWITCH_EDIT,i) == 0) { lpszCmdParam = SHGetFileName(lpszCmdParam); _fFileForEdit = TRUE; _SH.autoConnectEnabled = FALSE; }
else if (memcmp(szParam, SWITCH_MIGRATE,i) == 0) { _fMigrateOnly = TRUE; }
else if (memcmp(szParam, SWITCH_CONSOLE,i) == 0) { SH_SetCmdConnectToConsole(TRUE); }
/************************************************************************/ /* Not a recognized switch. Bring up usage */ /************************************************************************/ else { TRC_NRM((TB,_T("Invalid CmdLine switch - Display Usage AND EXIT %s"), szParam)); DCTCHAR szCmdLineUsage[4096]; //Long string here.
DCTCHAR szUsageTitle[256]; if (!LoadString(_hInstance, UI_IDS_USAGE_TITLE, szUsageTitle, SIZECHAR(szUsageTitle))) { TRC_ERR((TB,_T("Error loading UI_IDS_USAGE_TITLE"))); return NULL; }
if (!LoadString(_hInstance, UI_IDS_CMD_LINE_USAGE, szCmdLineUsage, SIZECHAR(szCmdLineUsage))) { TRC_NRM((TB,_T("Error loading UI_IDS_CMD_LINE_USAGE"))); return NULL; }
MessageBox(NULL, szCmdLineUsage, szUsageTitle, MB_ICONINFORMATION | MB_OK);
return NULL; }
DC_END_FN();
return(lpszCmdParam); }
/****************************************************************************/ /* Name: SHGetServer */ /* */ /* Purpose: Retrieves the server name (if specified) */ /* */ /* Returns: Nothing */ /* */ /* Params: IN - lpszCmdParam */ /* */ /****************************************************************************/ LPTSTR CSH::SHGetServer(LPTSTR lpszCmdParam) { DC_BEGIN_FN("SHGetServer"); if (!lpszCmdParam) { return NULL; }
/************************************************************************/ /* Retrieve the server */ /************************************************************************/ lpszCmdParam = SHGetCmdLineString(lpszCmdParam, _SH.szCommandLineServer, SIZECHAR(_SH.szCommandLineServer) -1);
DC_END_FN(); return lpszCmdParam; }
/****************************************************************************/ /* Name: SHGetSession */ /* */ /* Purpose: Retrieves the session name (if specified) */ /* */ /* Returns: Nothing */ /* */ /* Params: IN - lpszCmdParam */ /* */ /****************************************************************************/ LPTSTR CSH::SHGetSession(LPTSTR lpszCmdParam) { BOOL fQuote = FALSE;
DC_BEGIN_FN("SHGetSession");
TRC_ASSERT((_SH.fRegDefault == TRUE), (TB,_T("Invalid CmdLine syntax - session respecified.")));
// Retrieve the reg session
lpszCmdParam = SHGetCmdLineString(lpszCmdParam, _SH.regSession, SIZECHAR(_SH.regSession) -1); // In the non-default session, display the session name. Choose the
// appropriate connected/disconnected strings.
TRC_DBG((TB, _T("Named session")));
_SH.fRegDefault = FALSE; _SH.connectedStringID = UI_IDS_FRAME_TITLE_CONNECTED; _SH.disconnectedStringID = UI_IDS_FRAME_TITLE_DISCONNECTED;
DC_END_FN();
return(lpszCmdParam); }
LPTSTR CSH::SHGetFileName(LPTSTR lpszCmdParam) { BOOL fQuote = FALSE;
DC_BEGIN_FN("SHGetSession");
TRC_ASSERT((_SH.fRegDefault == TRUE), (TB,_T("Invalid CmdLine syntax - session respecified.")));
// Retrieve the filename
lpszCmdParam = SHGetCmdLineString(lpszCmdParam, _szFileName, SIZECHAR(_szFileName) -1); _SH.fRegDefault = FALSE; _SH.connectedStringID = UI_IDS_FRAME_TITLE_CONNECTED; _SH.disconnectedStringID = UI_IDS_FRAME_TITLE_DISCONNECTED;
DC_END_FN();
return(lpszCmdParam); }
/****************************************************************************/ /* Name: SHGetCmdLineString */ /* */ /* Purpose: Retrieve a string parameter */ /* */ /* Returns: Nothing */ /* */ /* Params: IN - lpszCmdParam */ /* */ /****************************************************************************/ LPTSTR CSH::SHGetCmdLineString(LPTSTR lpszCmdParam, LPTSTR lpszDest, DCINT cbDestLen) { DCINT i; BOOL fQuote = FALSE;
DC_BEGIN_FN("SHGetCmdLineString");
TRC_ASSERT(lpszCmdParam && lpszDest && cbDestLen, (TB, _T("SHGetCmdLineString. Invalid param(s)\n"))); if (!lpszCmdParam || !lpszDest || !cbDestLen) { return NULL; }
/************************************************************************/ /* Retrieve a command line string parameter */ /************************************************************************/ while (*lpszCmdParam == _T(' ')) lpszCmdParam++;
if (*lpszCmdParam == _T('=') || *lpszCmdParam == _T(':')) lpszCmdParam++;
while (*lpszCmdParam == _T(' ')) lpszCmdParam++;
i=0;
while (*lpszCmdParam) { switch (*lpszCmdParam) { case _T('"'): fQuote = !fQuote; lpszCmdParam++; break;
case _T(' '): if (!fQuote) { lpszCmdParam++; DC_QUIT; } // else fall through
default: if (i < cbDestLen) lpszDest[i++] = *lpszCmdParam; lpszCmdParam++; } }
DC_EXIT_POINT: DC_END_FN(); lpszDest[i] = 0; return lpszCmdParam; }
/****************************************************************************/ /* Name: SHGetCmdLineInt */ /* */ /* Purpose: Retrieves an integer parameter */ /* */ /* Returns: Nothing */ /* */ /* Params: IN - lpszCmdParam, OUT- PInt */ /* */ /****************************************************************************/ LPTSTR CSH::SHGetCmdLineInt(LPTSTR lpszCmdParam, PDCUINT pInt) { DC_BEGIN_FN("SHGetCmdLineInt"); if (!pInt) { return NULL; } if (!lpszCmdParam) { return NULL; }
/************************************************************************/ /* Retrieve an integer parameter */ /************************************************************************/ while (*lpszCmdParam == _T(' ')) lpszCmdParam++;
if (*lpszCmdParam == _T('=') || *lpszCmdParam == _T(':')) lpszCmdParam++;
while (*lpszCmdParam == _T(' ')) lpszCmdParam++;
DCUINT readInt = 0; while (*lpszCmdParam) { if (*lpszCmdParam == _T(' ')) break;
if (_istdigit(*lpszCmdParam)) { DCINT digit = *lpszCmdParam - _T('0'); TRC_ASSERT(digit >=0 && digit <=9, (TB,_T("digit read error\n"))); if (digit <0 || digit >9) { break; } readInt = readInt * 10 + digit; } else { break; } lpszCmdParam++; }
*pInt = readInt;
DC_END_FN(); return lpszCmdParam; }
/****************************************************************************/ /* Name: SHGetCacheToClear */ /* */ /* Purpose: Retrieves the cache type (e.g. bitmap) to be cleared */ /* */ /* Returns: Nothing */ /* */ /* Params: IN - lpszCmdParam */ /* */ /****************************************************************************/ LPTSTR CSH::SHGetCacheToClear(LPTSTR lpszCmdParam) { DCINT i; TCHAR cacheType[10];
DC_BEGIN_FN("SHGetCacheToClear");
/************************************************************************/ /* Retrieve the cache type */ /************************************************************************/ while (*lpszCmdParam == _T(' ')) lpszCmdParam++;
if (*lpszCmdParam == _T('=') || *lpszCmdParam == _T(':')) lpszCmdParam++;
while (*lpszCmdParam == _T(' ')) lpszCmdParam++;
i=0;
while (*lpszCmdParam) { if (*lpszCmdParam == _T(' ')) break;
if (i < sizeof(cacheType) / sizeof(DCTCHAR) -1) #ifdef UNICODE
cacheType[i++] = (DCTCHAR) towupper(*lpszCmdParam); #else // UNICODE
cacheType[i++] = (DCTCHAR) toupper(*lpszCmdParam); #endif // UNICODE
lpszCmdParam++; }
cacheType[i] = 0;
if (memcmp(cacheType, "BITMAP", i) == 0) { _SH.fClearPersistBitmapCache = TRUE; } else { TRC_NRM((TB,_T("Invalid Cache Type - %s"), cacheType)); }
DC_END_FN();
return(lpszCmdParam); }
//
// Take the session in _SH.regSession and figure out
// if it is a file or a registry session
//
// We need to do this because for compatability reasons
// the client has to be able to support both a file name
// and the registry session name as default command line
// params (enter this logic to determine which is which).
//
//
// Return TRUE if it's a valid reg or connection param
// or FALSE otherwise
//
BOOL CSH::ParseFileOrRegConnectionParam() { BOOL fRet = TRUE; DC_BEGIN_FN("ParseFileOrRegConnectionParam");
//
// If a connection parameter is specified that is
// different from the default
//
if(_tcscmp(_SH.regSession, SH_DEFAULT_REG_SESSION)) {
//
// A connection parameter is specified
// check for the three possible cases
// 1) it's an RDP file
// 2) it's a registry connection
// 3) it's INVALID!
//
//a) check if the session is really a file
if (SH_FileExists(_SH.regSession)) { _tcsncpy(_szFileName, _SH.regSession, SIZECHAR(_szFileName)); _fFileForConnect = TRUE; _SH.autoConnectEnabled = TRUE; SetRegSessionSpecified(FALSE); } else if (SH_TSSettingsRegKeyExists(_SH.regSession)) {
//Assume it's an old registry style session name
SetRegSessionSpecified(TRUE); } else { TRC_ERR((TB,_T("Reg session is neither file nore reg key: %s"), _SH.regSession)); fRet = FALSE; } }
DC_END_FN(); return fRet; }
#ifndef OS_WINCE
//
// Copy of StrRetToStrW from \shell\shlwapi\strings.c
//
//
// dupe a string using the task allocator for returing from a COM interface
//
HRESULT XSHStrDupA(LPCSTR psz, WCHAR **ppwsz) { WCHAR *pwsz; DWORD cch;
//RIPMSG(psz && IS_VALID_STRING_PTRA(psz, -1), "SHStrDupA: Caller passed invalid psz");
if (psz) { cch = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0); pwsz = (WCHAR *)CoTaskMemAlloc((cch + 1) * sizeof(WCHAR)); } else pwsz = NULL;
*((PVOID UNALIGNED64 *) ppwsz) = pwsz;
if (pwsz) { MultiByteToWideChar(CP_ACP, 0, psz, -1, *ppwsz, cch); return S_OK; } return E_OUTOFMEMORY; }
HRESULT XStrRetToStrW(LPSTRRET psr, LPCITEMIDLIST pidl, WCHAR **ppsz) { HRESULT hres = S_OK;
switch (psr->uType) { case STRRET_WSTR: *ppsz = psr->DUMMYUNIONNAME.pOleStr; psr->DUMMYUNIONNAME.pOleStr = NULL; // avoid alias
hres = *ppsz ? S_OK : E_FAIL; break;
case STRRET_OFFSET: hres = XSHStrDupA(STRRET_OFFPTR(pidl, psr), ppsz); break;
case STRRET_CSTR: hres = XSHStrDupA(psr->DUMMYUNIONNAME.cStr, ppsz); break;
default: *ppsz = NULL; hres = E_FAIL; } return hres; }
#endif
|