#include #include #include #include #include #include #include "resource.h" #include "migutil.h" #include "migwiz.h" #include #include #include extern "C" { #include "ism.h" #include "modules.h" } PTSTR g_Explorer = NULL; ///////////////// // definitions #ifndef ARRAYSIZE #define ARRAYSIZE(x) ((sizeof(x)) / (sizeof(x[0]))) #endif CRITICAL_SECTION g_csDialogCritSection; BOOL g_fUberCancel; BOOL g_LogOffSystem = FALSE; BOOL g_RebootSystem = FALSE; BOOL g_OFStatus = FALSE; ////////////////////////////////////////////////////////////////////////////////////// LPSTR _ConvertToAnsi(UINT cp, LPCWSTR pcwszSource) { // Locals HRESULT hr=S_OK; INT cchNarrow; INT cchWide; LPSTR pszDup=NULL; // No Source if (pcwszSource == NULL) goto exit; // Length cchWide = lstrlenW(pcwszSource) + 1; // Determine how much space is needed for translated widechar cchNarrow = WideCharToMultiByte(cp, 0, pcwszSource, cchWide, NULL, 0, NULL, NULL); // Error if (cchNarrow == 0) goto exit; // Alloc temp buffer pszDup = (LPSTR)LocalAlloc(LPTR, cchNarrow + 1); if (NULL == pszDup) { goto exit; } // Do the actual translation cchNarrow = WideCharToMultiByte(cp, 0, pcwszSource, cchWide, pszDup, cchNarrow + 1, NULL, NULL); // Error if (cchNarrow == 0) { if (NULL != pszDup) { free(pszDup); } goto exit; } exit: // Done return(pszDup); } ////////////////////////////////////////////////////////////////////////////////////// LPWSTR _ConvertToUnicode(UINT cp, LPCSTR pcszSource) { // Locals HRESULT hr=S_OK; INT cchNarrow; INT cchWide; LPWSTR pwszDup=NULL; // No Source if (pcszSource == NULL) goto exit; // Length cchNarrow = lstrlenA(pcszSource) + 1; // Determine how much space is needed for translated widechar cchWide = MultiByteToWideChar(cp, MB_PRECOMPOSED, pcszSource, cchNarrow, NULL, 0); // Error if (cchWide == 0) goto exit; // Alloc temp buffer pwszDup = (LPWSTR)LocalAlloc(LPTR, cchWide * sizeof (WCHAR)); if (NULL == pwszDup) { goto exit; } // Do the actual translation cchWide = MultiByteToWideChar(cp, MB_PRECOMPOSED, pcszSource, cchNarrow, pwszDup, cchWide+1); // Error if (cchWide == 0) { if (NULL != pwszDup) { free(pwszDup); } goto exit; } exit: // Done return pwszDup; } ////////////////////////////////////////////////////////////////////////////////////// HRESULT _SHUnicodeToAnsi(LPWSTR pwszIn, LPSTR pszOut, UINT cchOut) { // Locals HRESULT hr = E_INVALIDARG; INT cchNarrow; INT cchWide; // No Source if (pwszIn && pszOut) { // Length cchWide = lstrlenW(pwszIn) + 1; // Determine how much space is needed for translated widechar cchNarrow = WideCharToMultiByte(CP_ACP, 0, pwszIn, cchWide, NULL, 0, NULL, NULL); // Error if (cchNarrow > 0) { // Do the actual translation cchNarrow = WideCharToMultiByte(CP_ACP, 0, pwszIn, cchWide, pszOut, cchNarrow + 1, NULL, NULL); if (cchNarrow) { hr = S_OK; } } } return hr; } ////////////////////////////////////////////////////////////////////////////////////// HRESULT _SHAnsiToUnicode(LPSTR pszIn, LPWSTR pwszOut, UINT cchOut) { // Locals HRESULT hr = E_INVALIDARG; INT cchNarrow; INT cchWide; // No Source if (pszIn && pwszOut) { // Length cchNarrow = lstrlenA(pszIn) + 1; // Determine how much space is needed for translated widechar cchWide = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszIn, cchNarrow, NULL, 0); // Error if (cchWide > 0) { // Do the actual translation cchWide = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszIn, cchNarrow, pwszOut, cchWide+1); if (cchWide > 0) { hr = S_OK; } } } return hr; } ////////////////////////////////////////////////////////////////////////////////////// #ifdef UNICODE #define _StrRetToBuf _StrRetToBufW #else #define _StrRetToBuf _StrRetToBufA #endif #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))) STDAPI _StrRetToBufA(STRRET *psr, LPCITEMIDLIST pidl, LPSTR pszBuf, UINT cchBuf) { HRESULT hres = E_FAIL; switch (psr->uType) { case STRRET_WSTR: { LPWSTR pszStr = psr->pOleStr; // temp copy because SHUnicodeToAnsi may overwrite buffer if (pszStr) { _SHUnicodeToAnsi(pszStr, pszBuf, cchBuf); CoTaskMemFree(pszStr); // Make sure no one thinks things are allocated still psr->uType = STRRET_CSTR; psr->cStr[0] = 0; hres = S_OK; } } break; case STRRET_CSTR: StrCpyNA (pszBuf, psr->cStr, cchBuf); hres = S_OK; break; case STRRET_OFFSET: if (pidl) { StrCpyNA (pszBuf, STRRET_OFFPTR(pidl, psr), cchBuf); hres = S_OK; } break; } if (FAILED(hres) && cchBuf) *pszBuf = 0; return hres; } STDAPI _StrRetToBufW(STRRET *psr, LPCITEMIDLIST pidl, LPWSTR pszBuf, UINT cchBuf) { HRESULT hres = E_FAIL; switch (psr->uType) { case STRRET_WSTR: { LPWSTR pwszTmp = psr->pOleStr; if (pwszTmp) { StrCpyNW(pszBuf, pwszTmp, cchBuf); CoTaskMemFree(pwszTmp); // Make sure no one thinks things are allocated still psr->uType = STRRET_CSTR; psr->cStr[0] = 0; hres = S_OK; } } break; case STRRET_CSTR: _SHAnsiToUnicode(psr->cStr, pszBuf, cchBuf); hres = S_OK; break; case STRRET_OFFSET: if (pidl) { _SHAnsiToUnicode(STRRET_OFFPTR(pidl, psr), pszBuf, cchBuf); hres = S_OK; } break; } if (FAILED(hres) && cchBuf) *pszBuf = 0; return hres; } ////////////////////////////////////////////////////////////////////////////////////// INT_PTR _ExclusiveDialogBox(HINSTANCE hInstance, LPCTSTR lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc) { INT_PTR iRetVal = -1; EnterCriticalSection(&g_csDialogCritSection); if (!g_fUberCancel) { iRetVal = DialogBoxParam(hInstance, lpTemplate, hWndParent, lpDialogFunc, (LPARAM)hWndParent); } LeaveCriticalSection(&g_csDialogCritSection); return iRetVal; } int _ExclusiveMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) { int iRetVal = -1; EnterCriticalSection(&g_csDialogCritSection); if (!g_fUberCancel) { iRetVal = MessageBox(hWnd, lpText, lpCaption, uType); } LeaveCriticalSection(&g_csDialogCritSection); return iRetVal; } ////////////////////////////////////////////////////////////////////////////////////// int _ComboBoxEx_AddString(HWND hwndBox, LPTSTR ptsz) { COMBOBOXEXITEM item = {0}; item.mask = CBEIF_TEXT; item.iItem = ComboBox_GetCount(hwndBox); item.pszText = ptsz; return (INT) SendMessage(hwndBox, CBEM_INSERTITEM, 0, (LONG_PTR)&item); } ////////////////////////////////////////////////////////////////////////////////////// int _ComboBoxEx_SetItemData(HWND hwndBox, UINT iDex, LPARAM lParam) { COMBOBOXEXITEM item = {0}; item.mask = CBEIF_LPARAM; item.iItem = iDex; item.lParam = lParam; return (INT) SendMessage(hwndBox, CBEM_SETITEM, 0, (LONG_PTR)&item); } ////////////////////////////////////////////////////////////////////////////////////// int _ComboBoxEx_SetIcon(HWND hwndBox, LPTSTR sz, UINT iDex) { SHFILEINFO sfi = {0}; COMBOBOXEXITEM item = {0}; DWORD dwFlags = SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_USEFILEATTRIBUTES; if (SHGetFileInfo(sz, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), dwFlags)) { item.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE; item.iItem = iDex; item.iImage = sfi.iIcon; item.iSelectedImage = sfi.iIcon; return (INT) SendMessage(hwndBox, CBEM_SETITEM, 0, (LONG_PTR)&item); } return -1; } ////////////////////////////////////////////////////////////////////////////////////// int _GetRemovableDriveCount() { int iCount = 0; TCHAR szDrive[4] = TEXT("A:\\"); for (UINT uiCount = 0; uiCount < 26; uiCount++) { szDrive[0] = TEXT('A') + uiCount; if (DRIVE_REMOVABLE == GetDriveType(szDrive)) { iCount++; } } return iCount; } ////////////////////////////////////////////////////////////////////////////////////// TCHAR _GetRemovableDrive(int iDex) { int iCount = iDex; TCHAR szDrive[4] = TEXT("?:\\"); for (UINT uiCount = 0; uiCount < 26; uiCount++) { szDrive[0] = TEXT('A') + uiCount; if (DRIVE_REMOVABLE == GetDriveType(szDrive)) { if (!(iCount--)) { return szDrive[0]; } } } // ASSERT(FALSE); return '0'; // ERROR } ////////////////////////////////////////////////////////////////////////////////////// LPTSTR _GetRemovableDrivePretty(int iDex) { HRESULT hr; LPTSTR pszRetVal = NULL; WCHAR wszDrive[4] = L"A:\\"; wszDrive[0] = L'A' + _GetRemovableDrive(iDex) - TEXT('A'); IShellFolder* psfDesktop; hr = SHGetDesktopFolder(&psfDesktop); if (SUCCEEDED(hr)) { LPITEMIDLIST pidlDrive; hr = psfDesktop->ParseDisplayName(NULL, NULL, wszDrive, NULL, &pidlDrive, NULL); if (SUCCEEDED(hr)) { STRRET strret; hr = psfDesktop->GetDisplayNameOf(pidlDrive, SHGDN_INFOLDER, &strret); if (SUCCEEDED(hr)) { TCHAR szDisplayName[MAX_PATH]; if (SUCCEEDED(_StrRetToBuf(&strret, pidlDrive, szDisplayName, ARRAYSIZE(szDisplayName)))) { pszRetVal = StrDup(szDisplayName); } } } } return pszRetVal; } ////////////////////////////////////////////////////////////////////////////////////// BOOL _IsRemovableOrCDDrive(TCHAR chDrive) { UINT result = 0; if ( (chDrive >= TEXT('A') && chDrive <= TEXT('Z')) || (chDrive >= TEXT('a') && chDrive <= TEXT('z'))) { TCHAR szDrive[4] = TEXT("A:\\"); szDrive[0] = chDrive; result = GetDriveType (szDrive); return ((result == DRIVE_REMOVABLE) || (result == DRIVE_CDROM)); } return FALSE; } BOOL _IsValidDrive(TCHAR chDrive) { UINT result; if ( (chDrive >= TEXT('A') && chDrive <= TEXT('Z')) || (chDrive >= TEXT('a') && chDrive <= TEXT('z'))) { TCHAR szDrive[4] = TEXT("A:\\"); szDrive[0] = chDrive; result = GetDriveType(szDrive); if ((result == DRIVE_UNKNOWN) || (result == DRIVE_NO_ROOT_DIR) ) { return FALSE; } return TRUE; } return FALSE; } BOOL _IsValidStorePath(PCTSTR pszStore) { return (((pszStore[1] == TEXT(':')) && (pszStore[2] == TEXT('\\')) && (_IsValidDrive (pszStore [0]))) || ((pszStore[0] == TEXT('\\')) && (pszStore[1] == TEXT('\\')) && (_tcschr (pszStore + 2, TEXT('\\')) != NULL))); } BOOL _CreateFullDirectory(PCTSTR pszPath) { TCHAR pathCopy [MAX_PATH]; PTSTR p; BOOL b = TRUE; StrCpyN (pathCopy, pszPath, ARRAYSIZE(pathCopy)); // // Advance past first directory // if (pathCopy[1] == TEXT(':') && pathCopy[2] == TEXT('\\')) { // // :\ case // p = _tcschr (&pathCopy[3], TEXT('\\')); } else if (pathCopy[0] == TEXT('\\') && pathCopy[1] == TEXT('\\')) { // // UNC case // p = _tcschr (pathCopy + 2, TEXT('\\')); if (p) { p = _tcschr (p + 1, TEXT('\\')); if (p) { p = _tcsinc (p); if (p) { p = _tcschr (p, TEXT('\\')); } } } } else { // // Relative dir case // p = _tcschr (pathCopy, TEXT('\\')); } // // Make all directories along the path // while (p) { *p = 0; b = CreateDirectory (pathCopy, NULL); if (!b && GetLastError() == ERROR_ALREADY_EXISTS) { b = TRUE; } if (!b) { break; } *p = TEXT('\\'); p = _tcsinc (p); if (p) { p = _tcschr (p + 1, TEXT('\\')); } } // // At last, make the FullPath directory // if (b) { b = CreateDirectory (pathCopy, NULL); if (!b && GetLastError() == ERROR_ALREADY_EXISTS) { b = TRUE; } } return b; } PTSTR pGoBack ( IN PTSTR LastChar, IN PTSTR FirstChar, IN UINT NumWacks ) { LastChar = _tcsdec (FirstChar, LastChar); while (NumWacks && LastChar && (LastChar >= FirstChar)) { if (_tcsnextc (LastChar) == TEXT('\\')) { NumWacks --; } LastChar = _tcsdec (FirstChar, LastChar); } if (NumWacks) { return NULL; } return LastChar + 2; } UINT pCountDots ( IN PCTSTR PathSeg ) { UINT numDots = 0; while (PathSeg && *PathSeg) { if (_tcsnextc (PathSeg) != TEXT('.')) { return 0; } numDots ++; PathSeg = _tcsinc (PathSeg); } return numDots; } PCTSTR _SanitizePath ( IN PCTSTR FileSpec ) { TCHAR pathSeg [MAX_PATH]; PCTSTR wackPtr; UINT dotNr; PTSTR newPath = (PTSTR)IsmDuplicateString (FileSpec); PTSTR newPathPtr = newPath; BOOL firstPass = TRUE; UINT max; BOOL removeLastWack = FALSE; do { removeLastWack = FALSE; ZeroMemory (pathSeg, sizeof (pathSeg)); wackPtr = _tcschr (FileSpec, TEXT('\\')); if (wackPtr) { if (firstPass && (wackPtr == FileSpec)) { // this one starts with a wack, let's see if we have double wacks wackPtr = _tcsinc (wackPtr); if (!wackPtr) { IsmReleaseMemory (newPath); return NULL; } if (_tcsnextc (wackPtr) == TEXT('\\')) { // this one starts with a double wack wackPtr = _tcsinc (wackPtr); if (!wackPtr) { IsmReleaseMemory (newPath); return NULL; } wackPtr = _tcschr (wackPtr, TEXT('\\')); } else { wackPtr = _tcschr (wackPtr, TEXT('\\')); } } firstPass = FALSE; if (wackPtr) { max = (wackPtr - FileSpec) * sizeof (TCHAR); CopyMemory (pathSeg, FileSpec, min (MAX_PATH * sizeof (TCHAR), max)); FileSpec = _tcsinc (wackPtr); } else { max = _tcslen (FileSpec) * sizeof (TCHAR); CopyMemory (pathSeg, FileSpec, min (MAX_PATH * sizeof (TCHAR), max)); } } else { max = _tcslen (FileSpec) * sizeof (TCHAR); if (max == 0) { removeLastWack = TRUE; } CopyMemory (pathSeg, FileSpec, min (MAX_PATH * sizeof (TCHAR), max)); } if (*pathSeg) { dotNr = pCountDots (pathSeg); if (dotNr>1) { newPathPtr = pGoBack (newPathPtr, newPath, dotNr); if (newPathPtr == NULL) { IsmReleaseMemory (newPath); return NULL; } } else if (dotNr != 1) { _tcscpy (newPathPtr, pathSeg); newPathPtr = _tcschr (newPathPtr, 0); if (wackPtr) { *newPathPtr = TEXT('\\'); //we increment this because we know that \ is a single byte character. newPathPtr ++; } } else { removeLastWack = TRUE; } } } while (wackPtr); if (removeLastWack && (newPathPtr > newPath)) { newPathPtr --; } *newPathPtr = 0; return newPath; } BOOL _IsValidStore(LPTSTR pszStore, BOOL bCreate, HINSTANCE hinst, HWND hwnd) { TCHAR szSerialStr[] = TEXT("COM"); TCHAR szParallelStr[] = TEXT("LPT"); PTSTR lpExpStore; PCTSTR sanitizedStore; BOOL fValid = FALSE; // // Skip past leading space, since PathIsDirectory() on Win9x // incorrectly assumes spaces are a valid dir. // while (_istspace (*pszStore)) pszStore++; // // No relative paths allowed. // if (*pszStore == TEXT('.')) return FALSE; if ((_tcsnicmp (pszStore, szSerialStr, (sizeof (szSerialStr) / sizeof (TCHAR)) - 1) == 0) || (_tcsnicmp (pszStore, szParallelStr, (sizeof (szParallelStr) / sizeof (TCHAR)) - 1) == 0) ) { return TRUE; } lpExpStore = (PTSTR)IsmExpandEnvironmentString (PLATFORM_SOURCE, S_SYSENVVAR_GROUP, pszStore, NULL); sanitizedStore = _SanitizePath (lpExpStore); if (sanitizedStore) { if (PathIsDirectory(sanitizedStore)) // if a normal directory { fValid = TRUE; } else if (lstrlen(sanitizedStore) == 3 && sanitizedStore[1] == TEXT(':') && sanitizedStore[2] == TEXT('\\') && _IsRemovableOrCDDrive(sanitizedStore[0])) { fValid = TRUE; } else if (lstrlen(sanitizedStore) == 2 && sanitizedStore[1] == TEXT(':') && _IsRemovableOrCDDrive(sanitizedStore[0])) { fValid = TRUE; } else { if ((bCreate) && (_IsValidStorePath (sanitizedStore))) { TCHAR szTitle[MAX_LOADSTRING]; TCHAR szLoadString[MAX_LOADSTRING]; LoadString(hinst, IDS_MIGWIZTITLE, szTitle, ARRAYSIZE(szTitle)); LoadString(hinst, IDS_ASKCREATEDIR, szLoadString, ARRAYSIZE(szLoadString)); if (_ExclusiveMessageBox(hwnd, szLoadString, szTitle, MB_YESNO) == IDYES) { if (_CreateFullDirectory (sanitizedStore)) { fValid = TRUE; } } } } if (fValid) { _tcsncpy (pszStore, sanitizedStore, MAX_PATH); } IsmReleaseMemory (sanitizedStore); sanitizedStore = NULL; } IsmReleaseMemory (lpExpStore); return fValid; } ////////////////////////////////////////////////////////////////////////////////////// INT _ComboBoxEx_AddDrives(HWND hwndBox) { INT result = -1; ComboBox_ResetContent(hwndBox); WCHAR wszDrive[4] = L"A:\\"; TCHAR szDrive[4] = TEXT("A:\\"); for (UINT uiCount = 0; uiCount < (UINT)_GetRemovableDriveCount(); uiCount++) { szDrive[0] = _GetRemovableDrive(uiCount); int iDex = _ComboBoxEx_AddString(hwndBox, _GetRemovableDrivePretty(uiCount)); _ComboBoxEx_SetIcon(hwndBox, szDrive, iDex); _ComboBoxEx_SetItemData(hwndBox, iDex, (LPARAM)StrDup(szDrive)); result = 0; } ComboBox_SetCurSel(hwndBox, result); return result; } ////////////////////////////////////////////////////////////////////////////////////// BOOL pIsComPortAccessible ( PCTSTR ComPort ) { HANDLE comPortHandle = NULL; comPortHandle = CreateFile (ComPort, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (comPortHandle != INVALID_HANDLE_VALUE) { CloseHandle (comPortHandle); return TRUE; } return FALSE; } INT _ComboBoxEx_AddCOMPorts(HWND hwndBox, INT SelectedPort) { INT iDex; INT index = 1; INT added = -1; TCHAR comPort [] = TEXT("COM0"); if (hwndBox) { // clear the combo box content SendMessage (hwndBox, CB_RESETCONTENT, 0, 0); } while (index < 10) { comPort [ARRAYSIZE(comPort) - 2] ++; if (pIsComPortAccessible (comPort)) { if (hwndBox) { iDex = SendMessage (hwndBox, CB_ADDSTRING, 0, (LPARAM)comPort); SendMessage (hwndBox, CB_SETITEMDATA, (WPARAM)iDex, (LPARAM)StrDup(comPort)); } added ++; } index ++; } if (added == -1) { return -1; } if ((added >= SelectedPort) && (SelectedPort != -1)) { if (hwndBox) { ComboBox_SetCurSel(hwndBox, SelectedPort); } return SelectedPort; } if (hwndBox) { // We want nothing to be selected in this combo box, this // is intentional. ComboBox_SetCurSel(hwndBox, -1); } return 0; } ////////////////////////////////////////////////////////////////////////////////////// int _GetIcon(LPTSTR psz) { SHFILEINFO sfi = {0}; SHGetFileInfo(psz, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_SMALLICON | SHGFI_SYSICONINDEX); return sfi.iIcon; } ////////////////////////////////////////////////////////////////////////////////////// HRESULT _ListView_AddDrives(HWND hwndList, LPTSTR pszNetworkName) { HRESULT hr = E_FAIL; if (ListView_DeleteAllItems(hwndList)) { LVITEM item = {0}; item.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_TEXT; if (pszNetworkName) { item.iItem = 0; // first item item.pszText = pszNetworkName; item.iImage = 0; // ISSUE: 0 is icon for sharing, is there a better way to do this? item.lParam = NULL; ListView_InsertItem(hwndList, &item); } IShellFolder* psfDesktop; hr = SHGetDesktopFolder(&psfDesktop); if (SUCCEEDED(hr)) { WCHAR wszDrive[4] = L"?:\\"; TCHAR tszDrive[4] = TEXT("?:\\"); for (int iDrive = 0; iDrive < _GetRemovableDriveCount(); iDrive++) { tszDrive[0] = _GetRemovableDrive(iDrive); wszDrive[0] = L'A' + tszDrive[0] - TEXT('A'); LPITEMIDLIST pidlDrive; hr = psfDesktop->ParseDisplayName(NULL, NULL, wszDrive, NULL, &pidlDrive, NULL); if (SUCCEEDED(hr)) { STRRET strret; hr = psfDesktop->GetDisplayNameOf(pidlDrive, SHGDN_INFOLDER, &strret); if (SUCCEEDED(hr)) { TCHAR szDisplayName[MAX_PATH]; hr = _StrRetToBuf(&strret, pidlDrive, szDisplayName, ARRAYSIZE(szDisplayName)); if (SUCCEEDED(hr)) { item.iItem = 27; // this will force adding at the end item.pszText = szDisplayName; item.iImage = _GetIcon(tszDrive); item.lParam = (LPARAM)StrDup(tszDrive); ListView_InsertItem(hwndList, &item); } } } } } } return S_OK; } ////////////////////////////////////////////////////////////////////////////////////// HRESULT _CreateAnimationCtrl(HWND hwndDlg, HINSTANCE hinst, UINT idMarker, UINT idAnim, UINT idAvi, HWND* pHwndAnim) { HWND hwndAnim = NULL; RECT rc, rc1, rc2, rc3; POINT pt31, pt32; LONG tempXY = 0; PWORD tempX, tempY; POINT pt; // Create the animation control. hwndAnim = Animate_Create(hwndDlg, (ULONG_PTR) idAnim, WS_CHILD | ACS_TRANSPARENT, hinst); // Get the screen coordinates of the specified control button. GetWindowRect(GetDlgItem(hwndDlg, idMarker), &rc); // Get the screen coordinates of the specified control button. GetWindowRect(hwndAnim, &rc1); // Convert the coordinates of the lower-left corner to // client coordinates. pt.x = rc.left; pt.y = rc.bottom; ScreenToClient(hwndDlg, &pt); // Position the animation control below the Stop button. SetWindowPos(hwndAnim, 0, pt.x, pt.y + 20, 0, 0, SWP_NOZORDER | SWP_NOSIZE); // Get the screen coordinates of the specified control button. GetWindowRect(hwndAnim, &rc2); // Open the AVI clip, and show the animation control. Animate_Open(hwndAnim, MAKEINTRESOURCE(idAvi)); ShowWindow(hwndAnim, SW_SHOW); Animate_Play(hwndAnim, 0, -1, -1); // Get the screen coordinates of the specified control button. GetWindowRect(hwndAnim, &rc3); pt31.x = rc3.left; pt31.y = rc3.top; pt32.x = rc3.right; pt32.y = rc3.bottom; ScreenToClient(hwndDlg, &pt31); ScreenToClient(hwndDlg, &pt32); rc3.left = pt31.x; rc3.top = pt31.y; rc3.right = pt32.x; rc3.bottom = pt32.y; tempXY = GetDialogBaseUnits (); tempX = (PWORD)(&tempXY); tempY = tempX + 1; rc3.left = MulDiv (rc3.left, 4, *tempX); rc3.right = MulDiv (rc3.right, 4, *tempX); rc3.top = MulDiv (rc3.top, 8, *tempY); rc3.bottom = MulDiv (rc3.bottom, 8, *tempY); *pHwndAnim = hwndAnim; return S_OK; } ////////////////////////////////////////////////////////////////////////////////////// #define USER_SHELL_FOLDERS \ DEFMAC(CSIDL_ADMINTOOLS, TEXT("Administrative Tools"), -1, IDS_CSIDL_ADMINTOOLS) \ DEFMAC(CSIDL_ALTSTARTUP, TEXT("AltStartup"), -1, IDS_CSIDL_ALTSTARTUP) \ DEFMAC(CSIDL_APPDATA, TEXT("AppData"), -1, IDS_CSIDL_APPDATA) \ DEFMAC(CSIDL_BITBUCKET, TEXT("RecycleBinFolder"), -1, IDS_CSIDL_BITBUCKET) \ DEFMAC(CSIDL_CONNECTIONS, TEXT("ConnectionsFolder"), -1, IDS_CSIDL_CONNECTIONS) \ DEFMAC(CSIDL_CONTROLS, TEXT("ControlPanelFolder"), -1, IDS_CSIDL_CONTROLS) \ DEFMAC(CSIDL_COOKIES, TEXT("Cookies"), -1, IDS_CSIDL_COOKIES) \ DEFMAC(CSIDL_DESKTOP, TEXT("Desktop"), -1, IDS_CSIDL_DESKTOP) \ DEFMAC(CSIDL_DESKTOPDIRECTORY, TEXT("Desktop"), -1, IDS_CSIDL_DESKTOPDIRECTORY) \ DEFMAC(CSIDL_DRIVES, TEXT("DriveFolder"), -1, IDS_CSIDL_DRIVES) \ DEFMAC(CSIDL_FAVORITES, TEXT("Favorites"), -1, IDS_CSIDL_FAVORITES) \ DEFMAC(CSIDL_FONTS, TEXT("Fonts"), -1, IDS_CSIDL_FONTS) \ DEFMAC(CSIDL_HISTORY, TEXT("History"), -1, IDS_CSIDL_HISTORY) \ DEFMAC(CSIDL_INTERNET, TEXT("InternetFolder"), -1, IDS_CSIDL_INTERNET) \ DEFMAC(CSIDL_INTERNET_CACHE, TEXT("Cache"), -1, IDS_CSIDL_INTERNET_CACHE) \ DEFMAC(CSIDL_LOCAL_APPDATA, TEXT("Local AppData"), -1, IDS_CSIDL_LOCAL_APPDATA) \ DEFMAC(CSIDL_MYDOCUMENTS, TEXT("My Documents"), -1, IDS_CSIDL_MYDOCUMENTS) \ DEFMAC(CSIDL_MYMUSIC, TEXT("My Music"), -1, IDS_CSIDL_MYMUSIC) \ DEFMAC(CSIDL_MYPICTURES, TEXT("My Pictures"), -1, IDS_CSIDL_MYPICTURES) \ DEFMAC(CSIDL_MYVIDEO, TEXT("My Video"), -1, IDS_CSIDL_MYVIDEO) \ DEFMAC(CSIDL_NETHOOD, TEXT("NetHood"), -1, IDS_CSIDL_NETHOOD) \ DEFMAC(CSIDL_NETWORK, TEXT("NetworkFolder"), -1, IDS_CSIDL_NETWORK) \ DEFMAC(CSIDL_PERSONAL, TEXT("Personal"), -1, IDS_CSIDL_PERSONAL) \ DEFMAC(CSIDL_PROFILE, TEXT("Profile"), -1, IDS_CSIDL_PROFILE) \ DEFMAC(CSIDL_PROGRAM_FILES, TEXT("ProgramFiles"), -1, IDS_CSIDL_PROGRAM_FILES) \ DEFMAC(CSIDL_PROGRAM_FILESX86, TEXT("ProgramFilesX86"), -1, IDS_CSIDL_PROGRAM_FILESX86) \ DEFMAC(CSIDL_PROGRAM_FILES_COMMON, TEXT("CommonProgramFiles"), -1, IDS_CSIDL_PROGRAM_FILES_COMMON) \ DEFMAC(CSIDL_PROGRAM_FILES_COMMONX86, TEXT("CommonProgramFilesX86"), -1, IDS_CSIDL_PROGRAM_FILES_COMMONX86) \ DEFMAC(CSIDL_PROGRAMS, TEXT("Programs"), -1, IDS_CSIDL_PROGRAMS) \ DEFMAC(CSIDL_RECENT, TEXT("Recent"), -1, IDS_CSIDL_RECENT) \ DEFMAC(CSIDL_SENDTO, TEXT("SendTo"), -1, IDS_CSIDL_SENDTO) \ DEFMAC(CSIDL_STARTMENU, TEXT("Start Menu"), -1, IDS_CSIDL_STARTMENU) \ DEFMAC(CSIDL_STARTUP, TEXT("Startup"), -1, IDS_CSIDL_STARTUP) \ DEFMAC(CSIDL_SYSTEM, TEXT("System"), -1, IDS_CSIDL_SYSTEM) \ DEFMAC(CSIDL_SYSTEMX86, TEXT("SystemX86"), -1, IDS_CSIDL_SYSTEMX86) \ DEFMAC(CSIDL_TEMPLATES, TEXT("Templates"), -1, IDS_CSIDL_TEMPLATES) \ DEFMAC(CSIDL_WINDOWS, TEXT("Windows"), -1, IDS_CSIDL_WINDOWS) \ #define COMMON_SHELL_FOLDERS \ DEFMAC(CSIDL_COMMON_ADMINTOOLS, TEXT("Common Administrative Tools"), CSIDL_ADMINTOOLS, IDS_CSIDL_COMMON_ADMINTOOLS) \ DEFMAC(CSIDL_COMMON_ALTSTARTUP, TEXT("Common AltStartup"), CSIDL_ALTSTARTUP, IDS_CSIDL_COMMON_ALTSTARTUP) \ DEFMAC(CSIDL_COMMON_APPDATA, TEXT("Common AppData"), CSIDL_APPDATA, IDS_CSIDL_COMMON_APPDATA) \ DEFMAC(CSIDL_COMMON_DESKTOPDIRECTORY, TEXT("Common Desktop"), CSIDL_DESKTOP, IDS_CSIDL_COMMON_DESKTOPDIRECTORY) \ DEFMAC(CSIDL_COMMON_DOCUMENTS, TEXT("Common Documents"), CSIDL_PERSONAL, IDS_CSIDL_COMMON_DOCUMENTS) \ DEFMAC(CSIDL_COMMON_FAVORITES, TEXT("Common Favorites"), CSIDL_FAVORITES, IDS_CSIDL_COMMON_FAVORITES) \ DEFMAC(CSIDL_COMMON_PROGRAMS, TEXT("Common Programs"), CSIDL_PROGRAMS, IDS_CSIDL_COMMON_PROGRAMS) \ DEFMAC(CSIDL_COMMON_STARTMENU, TEXT("Common Start Menu"), CSIDL_STARTMENU, IDS_CSIDL_COMMON_STARTMENU) \ DEFMAC(CSIDL_COMMON_STARTUP, TEXT("Common Startup"), CSIDL_STARTUP, IDS_CSIDL_COMMON_STARTUP) \ DEFMAC(CSIDL_COMMON_TEMPLATES, TEXT("Common Templates"), CSIDL_TEMPLATES, IDS_CSIDL_COMMON_TEMPLATES) \ // // This is the structure used for handling CSIDLs // typedef struct { INT DirId; PCTSTR DirStr; INT AltDirId; UINT DirResId; BOOL DirUser; } CSIDL_STRUCT, *PCSIDL_STRUCT; #define DEFMAC(did,dstr,adid,rid) {did,dstr,adid,rid,TRUE}, static CSIDL_STRUCT g_UserShellFolders[] = { USER_SHELL_FOLDERS {-1, NULL, -1, 0, FALSE} }; #undef DEFMAC #define DEFMAC(did,dstr,adid,rid) {did,dstr,adid,rid,FALSE}, static CSIDL_STRUCT g_CommonShellFolders[] = { COMMON_SHELL_FOLDERS {-1, NULL, -1, 0, FALSE} }; #undef DEFMAC PTSTR pFindSfPath ( IN PCTSTR FolderStr, IN BOOL UserFolder ) { HKEY key = NULL; PTSTR data; PTSTR expData; DWORD expDataSize; PTSTR result = NULL; LONG lResult; DWORD dataType; DWORD dataSize; if (!result) { if (UserFolder) { lResult = RegOpenKey (HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"), &key); } else { lResult = RegOpenKey (HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"), &key); } if ((lResult == ERROR_SUCCESS) && key) { dataSize = 0; lResult = RegQueryValueEx (key, FolderStr, NULL, &dataType, NULL, &dataSize); if ((lResult == ERROR_SUCCESS) && ((dataType == REG_SZ) || (dataType == REG_EXPAND_SZ)) ) { data = (PTSTR)LocalAlloc (LPTR, dataSize); if (data) { lResult = RegQueryValueEx (key, FolderStr, NULL, &dataType, (LPBYTE)data, &dataSize); if (lResult == ERROR_SUCCESS) { expDataSize = ExpandEnvironmentStrings (data, NULL, 0); if (expDataSize) { expData = (PTSTR)LocalAlloc (LPTR, (expDataSize + 1) * sizeof (TCHAR)); expDataSize = ExpandEnvironmentStrings (data, expData, expDataSize); if (!expDataSize) { LocalFree (expData); expData = NULL; } } if (expDataSize) { result = expData; LocalFree (data); } else { result = data; } } else { LocalFree (data); } } } CloseHandle (key); } } if (result && !(*result)) { LocalFree (result); result = NULL; } if (!result) { if (UserFolder) { lResult = RegOpenKey (HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"), &key); } else { lResult = RegOpenKey (HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"), &key); } if ((lResult == ERROR_SUCCESS) && key) { dataSize = 0; lResult = RegQueryValueEx (key, FolderStr, NULL, &dataType, NULL, &dataSize); if ((lResult == ERROR_SUCCESS) && ((dataType == REG_SZ) || (dataType == REG_EXPAND_SZ)) ) { data = (PTSTR)LocalAlloc (LPTR, dataSize); if (data) { lResult = RegQueryValueEx (key, FolderStr, NULL, &dataType, (LPBYTE)data, &dataSize); if (lResult == ERROR_SUCCESS) { expDataSize = ExpandEnvironmentStrings (data, NULL, 0); if (expDataSize) { expData = (PTSTR)LocalAlloc (LPTR, (expDataSize + 1) * sizeof (TCHAR)); expDataSize = ExpandEnvironmentStrings (data, expData, expDataSize); if (!expDataSize) { LocalFree (expData); expData = NULL; } } if (expDataSize) { result = expData; LocalFree (data); } else { result = data; } } else { LocalFree (data); } } } CloseHandle (key); } } if (result && !(*result)) { LocalFree (result); result = NULL; } return (PTSTR) result; } PTSTR GetShellFolderPath ( IN INT Folder, IN PCTSTR FolderStr, IN BOOL UserFolder, OUT LPITEMIDLIST *pidl //OPTIONAL ) { PTSTR result = NULL; HRESULT hResult; BOOL b; LPITEMIDLIST localpidl = NULL; IMalloc *mallocFn; if (pidl) { *pidl = NULL; } hResult = SHGetMalloc (&mallocFn); if (hResult != S_OK) { return NULL; } hResult = SHGetSpecialFolderLocation (NULL, Folder, &localpidl); if (hResult == S_OK) { result = (PTSTR) LocalAlloc (LPTR, MAX_PATH); if (result) { b = SHGetPathFromIDList (localpidl, result); if (b) { if (pidl) { *pidl = localpidl; } return result; } LocalFree (result); result = NULL; } } if (FolderStr) { result = pFindSfPath (FolderStr, UserFolder); } mallocFn->Free (localpidl); localpidl = NULL; return result; } typedef HRESULT (WINAPI SHBINDTOPARENT)(LPCITEMIDLIST pidl, REFIID riid, VOID **ppv, LPCITEMIDLIST *ppidlLast); typedef SHBINDTOPARENT *PSHBINDTOPARENT; HRESULT OurSHBindToParent ( IN LPCITEMIDLIST pidl, IN REFIID riid, OUT VOID **ppv, OUT LPCITEMIDLIST *ppidlLast ) { HRESULT hr = E_FAIL; HMODULE lib; PSHBINDTOPARENT shBindToParent = NULL; lib = LoadLibrary (TEXT("shell32.dll")); if (lib) { shBindToParent = (PSHBINDTOPARENT)GetProcAddress (lib, "SHBindToParent"); if (shBindToParent) { hr = shBindToParent (pidl, riid, ppv, ppidlLast); } } return hr; } ////////////////////////////////////////////////////////////////////////////////////// // if pctszPath corresponds to the path of one of the CSIDL_XXXX entries, then return // its "pretty name", else return the standard path name HRESULT _GetPrettyFolderName (HINSTANCE Instance, BOOL fNT4, LPCTSTR pctszPath, LPTSTR ptszName, UINT cchName) { UINT itemsIndex = 0; PCSIDL_STRUCT items[2] = {g_UserShellFolders, g_CommonShellFolders}; PCSIDL_STRUCT p; IMalloc *mallocFn; LPITEMIDLIST pidl = NULL; LPCITEMIDLIST pidlLast = NULL; IShellFolder* psf = NULL; HRESULT hr = S_OK; PTSTR szPath = NULL; PTSTR szAltPath = NULL; STRRET strret; TCHAR szDisplay1[2048]; TCHAR szDisplay2[2048]; BOOL checkAlternate = FALSE; BOOL found = FALSE; // First, we look to find the corresponding CSIDL if we can // If we can't we will just copy the IN path to the OUT path. for (itemsIndex = 0; itemsIndex < 2; itemsIndex ++) { p = items [itemsIndex]; while (!found && (p->DirId >= 0)) { szDisplay1 [0] = 0; szDisplay2 [0] = 0; pidl = NULL; pidlLast = NULL; szPath = NULL; psf = NULL; szPath = GetShellFolderPath (p->DirId, p->DirStr, p->DirUser, &pidl); if (szPath && (0 == StrCmpI(pctszPath, szPath))) { found = TRUE; if (pidl) { hr = OurSHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlLast); if (SUCCEEDED(hr) && psf && pidlLast) { hr = psf->GetDisplayNameOf (pidlLast, SHGDN_NORMAL, &strret); if (SUCCEEDED (hr)) { hr = _StrRetToBuf (&strret, pidlLast, szDisplay1, ARRAYSIZE(szDisplay1)); if (!SUCCEEDED (hr) || (0 == StrCmpI (szDisplay1, pctszPath))) { // Failed or we just got back the complete folder spec. We don't need that! szDisplay1 [0] = 0; } } } if (psf) { psf->Release (); psf = NULL; } } } if (pidl) { hr = SHGetMalloc (&mallocFn); if (SUCCEEDED (hr)) { mallocFn->Free (pidl); pidl = NULL; } } if (szPath) { LocalFree (szPath); szPath = NULL; } if (szDisplay1 [0] && (p->AltDirId >= 0)) { szPath = GetShellFolderPath (p->AltDirId, NULL, TRUE, &pidl); if (pidl && szPath) { hr = OurSHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlLast); if (SUCCEEDED(hr) && psf && pidlLast) { hr = psf->GetDisplayNameOf (pidlLast, SHGDN_INFOLDER, &strret); if (SUCCEEDED (hr)) { hr = _StrRetToBuf (&strret, pidlLast, szDisplay2, ARRAYSIZE(szDisplay2)); if (!SUCCEEDED (hr)) { szDisplay2 [0] = 0; } } } if (psf) { psf->Release (); psf = NULL; } } if (pidl) { hr = SHGetMalloc (&mallocFn); if (SUCCEEDED (hr)) { mallocFn->Free (pidl); pidl = NULL; } } if (szPath) { LocalFree (szPath); szPath = NULL; } } if (found) { if ((!szDisplay1 [0]) || (0 == StrCmpI (szDisplay1, szDisplay2))) { // we need to use the resource ID if (!LoadString (Instance, p->DirResId, ptszName, cchName)) { StrCpyN (ptszName, pctszPath, cchName); } } else { StrCpyN (ptszName, szDisplay1, cchName); } break; } p ++; } if (found) { break; } } if (!found) { StrCpyN (ptszName, pctszPath, cchName); } return S_OK; } ////////////////////////////////////////////////////////////////////////////////////// VOID _PopulateTree (HWND hwndTree, HTREEITEM hti, LPTSTR ptsz, UINT cch, HRESULT (*fct)(HINSTANCE, BOOL, LPCTSTR, LPTSTR, UINT cchName), DWORD dwFlags, HINSTANCE Instance, BOOL fNT4) { if (hwndTree && hti && ptsz) { // ISSUE: resolve flickering, this doesn't fix it EnableWindow (hwndTree, FALSE); TCHAR szDisplay[2048]; TCHAR szClean[2048]; TCHAR* ptszPtr = ptsz; TCHAR* ptszParam = NULL; while (*ptsz && (ptszPtr < (ptsz + cch))) { szDisplay[0] = 0; BOOL fOK = TRUE; LV_DATASTRUCT* plvds = (LV_DATASTRUCT*)LocalAlloc(LPTR, sizeof(LV_DATASTRUCT)); if (plvds) { plvds->fOverwrite = FALSE; StrCpyN(szClean, ptszPtr, ARRAYSIZE(szClean)); LPITEMIDLIST pidl = NULL; // if this is a filetype, restore the "*." before it, add pretty name if (dwFlags == POPULATETREE_FLAGS_FILETYPES) { TCHAR szPretty[2048]; if (FAILED(_GetPrettyTypeName(szClean, szPretty, ARRAYSIZE(szPretty)))) { szPretty[0] = 0; } memmove(szClean + 2, szClean, sizeof(szClean) - (2 * sizeof(TCHAR))); *szClean = TEXT('*'); *(szClean + 1) = TEXT('.'); if (szPretty[0]) { lstrcpy(szClean + lstrlen(szClean), TEXT(" - ")); lstrcpy(szClean + lstrlen(szClean), szPretty); } } if (fOK) { if (szDisplay[0]) // if we already have a display name, use that and store the clean name { plvds->pszPureName = StrDup(szClean); } else { if (fct) // if there's a pretty-fying function, use it { fct(Instance, fNT4, szClean, szDisplay, ARRAYSIZE(szDisplay)); plvds->pszPureName = StrDup(szClean); } else if (POPULATETREE_FLAGS_FILETYPES) // ISSUE: this is hacky, clean this up { StrCpyN(szDisplay, szClean, ARRAYSIZE(szDisplay)); plvds->pszPureName = StrDup(ptsz); } else { StrCpyN(szDisplay, szClean, ARRAYSIZE(szDisplay)); } } TV_INSERTSTRUCT tis = {0}; tis.hParent = hti; tis.hInsertAfter = TVI_SORT; tis.item.mask = TVIF_TEXT | TVIF_PARAM; tis.item.lParam = (LPARAM)plvds; tis.item.pszText = szDisplay; TreeView_InsertItem(hwndTree, &tis); } ptszPtr += (1 + lstrlen(ptszPtr)); } } EnableWindow (hwndTree, TRUE); } } ////////////////////////////////////////////////////////////////////////////////////// UINT _ListView_InsertItem(HWND hwndList, LPTSTR ptsz) { LVITEM lvitem = {0}; lvitem.mask = LVIF_TEXT; lvitem.iItem = ListView_GetItemCount(hwndList); lvitem.pszText = ptsz; return ListView_InsertItem(hwndList, &lvitem); } ////////////////////////////////////////////////////////////////////////////////////// HRESULT _GetPrettyTypeName(LPCTSTR pctszType, LPTSTR ptszPrettyType, UINT cchPrettyType) { HRESULT hr = E_FAIL; BOOL found = FALSE; TCHAR tszTypeName[MAX_PATH]; LPTSTR ptszType; TCHAR szTypeName[MAX_PATH]; DWORD cchTypeName = MAX_PATH; TCHAR szCmdLine[MAX_PATH]; DWORD cchCmdLine = MAX_PATH; DWORD dwType = REG_SZ; if (TEXT('*') == pctszType[0] && TEXT('.') == pctszType[1]) { ptszType = (LPTSTR)pctszType + 1; } else { tszTypeName[0] = TEXT('.'); lstrcpy(tszTypeName + 1, pctszType); ptszType = tszTypeName; } // let's find the progId if (ERROR_SUCCESS == SHGetValue(HKEY_CLASSES_ROOT, ptszType, NULL, &dwType, szTypeName, &cchTypeName)) { LONG result; DWORD cchPrettyName = cchPrettyType; PTSTR cmdPtr, resIdPtr; INT resId; HMODULE dllModule; // let's see if this progId has the FriendlyTypeName value name if (ERROR_SUCCESS == SHGetValue(HKEY_CLASSES_ROOT, szTypeName, TEXT("FriendlyTypeName"), &dwType, szCmdLine, &cchCmdLine)) { cmdPtr = szCmdLine; if (_tcsnextc (cmdPtr) == TEXT('@')) { cmdPtr = _tcsinc (cmdPtr); } if (cmdPtr) { resIdPtr = _tcsrchr (cmdPtr, TEXT(',')); if (resIdPtr) { *resIdPtr = 0; resIdPtr ++; } } if (cmdPtr && resIdPtr) { resId = _ttoi (resIdPtr); if (resId < 0) { // let's load the resource string from that PE file // use resIdPtr to access the string resource dllModule = LoadLibraryEx (cmdPtr, NULL, LOAD_LIBRARY_AS_DATAFILE); if (dllModule) { found = (LoadString (dllModule, (UINT)(-resId), ptszPrettyType, cchPrettyName) > 0); hr = S_OK; FreeLibrary (dllModule); } } } } if ((!found) && (ERROR_SUCCESS == SHGetValue(HKEY_CLASSES_ROOT, szTypeName, NULL, &dwType, ptszPrettyType, &cchPrettyName))) { hr = S_OK; } } return hr; } ////////////////////////////////////////////////////////////////////////////////////// BOOL _DriveIdIsFloppyNT(int iDrive) { BOOL fRetVal = FALSE; HANDLE hDevice; UINT i; TCHAR szTemp[] = TEXT("\\\\.\\a:"); if (iDrive >= 0 && iDrive < 26) { szTemp[4] += (TCHAR)iDrive; hDevice = CreateFile(szTemp, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE != hDevice) { DISK_GEOMETRY rgGeometry[15]; DWORD cbIn = sizeof(rgGeometry); DWORD cbReturned; if (DeviceIoControl(hDevice, IOCTL_DISK_GET_MEDIA_TYPES, NULL, 0, rgGeometry, cbIn, &cbReturned, NULL)) { UINT cStructReturned = cbReturned / sizeof(DISK_GEOMETRY); for (i = 0; i < cStructReturned; i++) { switch (rgGeometry[i].MediaType) { case F5_1Pt2_512: case F3_1Pt44_512: case F3_2Pt88_512: case F3_20Pt8_512: case F3_720_512: case F5_360_512: case F5_320_512: case F5_320_1024: case F5_180_512: case F5_160_512: fRetVal = TRUE; break; case Unknown: case RemovableMedia: case FixedMedia: default: break; } } } CloseHandle (hDevice); } } return fRetVal; } /////////////////////////////////////////// #define DEVPB_DEVTYP_525_0360 0 #define DEVPB_DEVTYP_525_1200 1 #define DEVPB_DEVTYP_350_0720 2 #define DEVPB_DEVTYP_350_1440 7 #define DEVPB_DEVTYP_350_2880 9 #define DEVPB_DEVTYP_FIXED 5 #define DEVPB_DEVTYP_NECHACK 4 // for 3rd FE floppy #define DEVPB_DEVTYP_350_120M 6 #define CARRY_FLAG 0x01 #define VWIN32_DIOC_DOS_IOCTL 1 // DIOCRegs // Structure with i386 registers for making DOS_IOCTLS // vwin32 DIOC handler interprets lpvInBuffer , lpvOutBuffer to be this struc. // and does the int 21 // reg_flags is valid only for lpvOutBuffer->reg_Flags typedef struct DIOCRegs { DWORD reg_EBX; DWORD reg_EDX; DWORD reg_ECX; DWORD reg_EAX; DWORD reg_EDI; DWORD reg_ESI; DWORD reg_Flags; } DIOC_REGISTERS; #pragma pack(1) typedef struct _DOSDPB { BYTE specialFunc; // BYTE devType; // WORD devAttr; // WORD cCyl; // number of cylinders BYTE mediaType; // WORD cbSec; // Bytes per sector BYTE secPerClus; // Sectors per cluster WORD cSecRes; // Reserved sectors BYTE cFAT; // FATs WORD cDir; // Root Directory Entries WORD cSec; // Total number of sectors in image BYTE bMedia; // Media descriptor WORD secPerFAT; // Sectors per FAT WORD secPerTrack; // Sectors per track WORD cHead; // Heads DWORD cSecHidden; // Hidden sectors DWORD cTotalSectors; // Total sectors, if cbSec is zero BYTE reserved[6]; // } DOSDPB, *PDOSDPB; #pragma pack() BOOL _DriveIOCTL(int iDrive, int cmd, void *pvIn, DWORD dwIn, void *pvOut, DWORD dwOut, BOOL fFileSystem = FALSE, HANDLE handle = INVALID_HANDLE_VALUE) { BOOL fHandlePassedIn = TRUE; BOOL fSuccess = FALSE; DWORD dwRead; if (INVALID_HANDLE_VALUE == handle) { handle = CreateFileA("\\\\.\\VWIN32", 0, 0, 0, 0, FILE_FLAG_DELETE_ON_CLOSE, 0); fHandlePassedIn = FALSE; } if (INVALID_HANDLE_VALUE != handle) { DIOC_REGISTERS reg; // // On non-NT, we talk to VWIN32, issuing reads (which are converted // internally to DEVIOCTLs) // // this is a real hack (talking to VWIN32) on NT we can just // open the device, we dont have to go through VWIN32 // reg.reg_EBX = (DWORD)iDrive + 1; // make 1 based drive number reg.reg_EDX = (DWORD)(ULONG_PTR)pvOut; // out buffer reg.reg_ECX = cmd; // device specific command code reg.reg_EAX = 0x440D; // generic read ioctl reg.reg_Flags = 0x0001; // flags, assume error (carry) DeviceIoControl(handle, VWIN32_DIOC_DOS_IOCTL, ®, sizeof(reg), ®, sizeof(reg), &dwRead, NULL); fSuccess = !(reg.reg_Flags & 0x0001); if (!fHandlePassedIn) CloseHandle(handle); } return fSuccess; } BOOL _DriveIdIsFloppy9X(int iDrive) { DOSDPB SupportedGeometry; // s/b big enough for all BOOL fRet = FALSE; SupportedGeometry.specialFunc = 0; if (_DriveIOCTL(iDrive, 0x860, NULL, 0, &SupportedGeometry, sizeof(SupportedGeometry))) { switch( SupportedGeometry.devType ) { case DEVPB_DEVTYP_525_0360: case DEVPB_DEVTYP_525_1200: case DEVPB_DEVTYP_350_0720: case DEVPB_DEVTYP_350_1440: case DEVPB_DEVTYP_350_2880: fRet = TRUE; break; case DEVPB_DEVTYP_FIXED: case DEVPB_DEVTYP_NECHACK: // for 3rd FE floppy case DEVPB_DEVTYP_350_120M: fRet = FALSE; break; } } return fRet; } /////////////////////////////////////////// BOOL _DriveIdIsFloppy(BOOL fIsNT, int iDrive) { if (fIsNT) { return _DriveIdIsFloppyNT(iDrive); } else { return _DriveIdIsFloppy9X(iDrive); } } /////////////////////////////////////////// BOOL _DriveStrIsFloppy(BOOL fIsNT, PCTSTR pszPath) { int iDrive; iDrive = towlower(pszPath[0]) - TEXT('a'); return _DriveIdIsFloppy(fIsNT, iDrive); } /////////////////////////////////////////// INT _GetFloppyNumber(BOOL fIsNT) { static int iFloppy = -1; static bool fInit = FALSE; if (!fInit) { DWORD dwLog = GetLogicalDrives(); for (int i = 0; i < 26; i++) { if( !((dwLog >> i) & 0x01) || !_DriveIdIsFloppy(fIsNT, i) ) { break; } else { iFloppy = i; } } fInit = TRUE; } return iFloppy; } //////////////////////////////////////////////////////// /* * StrCmpN - Compare n bytes * * returns See lstrcmp return values. */ #ifdef BIG_ENDIAN #define READNATIVEWORD(x) MAKEWORD(*(char*)(x), *(char*)((char*)(x) + 1)) #else #define READNATIVEWORD(x) MAKEWORD(*(char*)((char*)(x) + 1), *(char*)(x)) #endif /* * ChrCmp - Case sensitive character comparison for DBCS * Assumes w1, wMatch are characters to be compared * Return FALSE if they match, TRUE if no match */ __inline BOOL ChrCmpA_inline(WORD w1, WORD wMatch) { /* Most of the time this won't match, so test it first for speed. */ if (LOBYTE(w1) == LOBYTE(wMatch)) { if (IsDBCSLeadByte(LOBYTE(w1))) { return(w1 != wMatch); } return FALSE; } return TRUE; } BOOL _SetTextLoadString(HINSTANCE hInst, HWND hwnd, UINT idText) { TCHAR sz[MAX_LOADSTRING]; if (LoadString(hInst, idText, sz, ARRAYSIZE(sz))) { SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)sz); return TRUE; } else { return FALSE; } } typedef HANDLE (WINAPI CREATETOOLHELP32SNAPSHOT)(DWORD dwFlags, DWORD th32ProcessID); typedef CREATETOOLHELP32SNAPSHOT *PCREATETOOLHELP32SNAPSHOT; #ifdef UNICODE typedef BOOL (WINAPI PROCESS32FIRST)(HANDLE hSnapshot, LPPROCESSENTRY32W lppe); typedef BOOL (WINAPI PROCESS32NEXT)(HANDLE hSnapshot, LPPROCESSENTRY32W lppe); #else typedef BOOL (WINAPI PROCESS32FIRST)(HANDLE hSnapshot, LPPROCESSENTRY32 lppe); typedef BOOL (WINAPI PROCESS32NEXT)(HANDLE hSnapshot, LPPROCESSENTRY32 lppe); #endif typedef PROCESS32FIRST *PPROCESS32FIRST; typedef PROCESS32NEXT *PPROCESS32NEXT; VOID KillExplorer ( IN HINSTANCE Instance, IN HWND hwndDlg, IN PCTSTR Args ) { HANDLE h, h1; PROCESSENTRY32 pe; TCHAR szExplorerPath[MAX_PATH]; PCREATETOOLHELP32SNAPSHOT dynCreateToolhelp32Snapshot; PPROCESS32FIRST dynProcess32First; PPROCESS32NEXT dynProcess32Next; HMODULE lib; lib = LoadLibrary (TEXT("kernel32.dll")); if (!lib) { return; } dynCreateToolhelp32Snapshot = (PCREATETOOLHELP32SNAPSHOT) GetProcAddress (lib, "CreateToolhelp32Snapshot"); #ifdef UNICODE dynProcess32First = (PPROCESS32FIRST) GetProcAddress (lib, "Process32FirstW"); dynProcess32Next = (PPROCESS32NEXT) GetProcAddress (lib, "Process32NextW"); #else dynProcess32First = (PPROCESS32FIRST) GetProcAddress (lib, "Process32First"); dynProcess32Next = (PPROCESS32NEXT) GetProcAddress (lib, "Process32Next"); #endif __try { if (!dynCreateToolhelp32Snapshot || !dynProcess32Next || !dynProcess32First) { __leave; } h = dynCreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); if (h == INVALID_HANDLE_VALUE) { __leave; } GetWindowsDirectory (szExplorerPath, MAX_PATH); PathAppend (szExplorerPath, TEXT("explorer.exe")); pe.dwSize = sizeof (PROCESSENTRY32); if (dynProcess32First (h, &pe)) { do { if (!StrCmpI (pe.szExeFile, TEXT("explorer.exe")) || !StrCmpI (pe.szExeFile, szExplorerPath) ) { h1 = OpenProcess (PROCESS_TERMINATE, FALSE, pe.th32ProcessID); if (h1) { g_Explorer = StrDup (szExplorerPath); TerminateProcess (h1, 1); CloseHandle (h1); break; } } } while (dynProcess32Next (h, &pe)); } CloseHandle (h); } __finally { FreeLibrary (lib); } } typedef enum { MS_MAX_PATH, MS_NO_ARG, MS_BOOL, MS_INT, MS_RECT, MS_BLOB } METRICSTYLE; VOID __RefreshMetric ( IN METRICSTYLE msStyle, IN UINT uGetMetricId, IN UINT uSetMetricId, IN UINT uBlobSize ) { BYTE byBuffer[MAX_PATH * 4]; PVOID blob; switch (msStyle) { case MS_NO_ARG: SystemParametersInfo (uSetMetricId, 0, NULL, SPIF_SENDCHANGE); break; case MS_BLOB: blob = LocalAlloc (LPTR, uBlobSize); if (blob) { if (SystemParametersInfo (uGetMetricId, uBlobSize, blob, SPIF_UPDATEINIFILE)) { SystemParametersInfo (uSetMetricId, 0, blob, SPIF_SENDCHANGE); } LocalFree (blob); } break; case MS_RECT: if (SystemParametersInfo (uGetMetricId, 0, byBuffer, SPIF_UPDATEINIFILE)) { SystemParametersInfo (uSetMetricId, 0, byBuffer, SPIF_SENDCHANGE); } break; case MS_BOOL: if (SystemParametersInfo (uGetMetricId, 0, byBuffer, SPIF_UPDATEINIFILE)) { SystemParametersInfo (uSetMetricId, *((BOOL *) byBuffer), NULL, SPIF_SENDCHANGE); } break; case MS_INT: if (SystemParametersInfo (uGetMetricId, 0, byBuffer, SPIF_UPDATEINIFILE)) { SystemParametersInfo (uSetMetricId, *((UINT *) byBuffer), NULL, SPIF_SENDCHANGE); } break; case MS_MAX_PATH: if (SystemParametersInfo (uGetMetricId, MAX_PATH, byBuffer, SPIF_UPDATEINIFILE)) { SystemParametersInfo (uSetMetricId, 0, byBuffer, SPIF_SENDCHANGE); } break; } return; } VOID SwitchToClassicDesktop ( IN HINSTANCE Instance, IN HWND hwndDlg, IN PCTSTR Args ) { LONG result; HKEY key = NULL; TCHAR data[] = TEXT("0"); // // The only thing that we need to do is to turn off: // HKCU\Software\Microsoft\Windows\CurrentVersion\ThemeManager [ThemeActive] // result = RegOpenKeyEx ( HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager"), 0, KEY_WRITE, &key ); if ((result == ERROR_SUCCESS) && (key) ) { result = RegSetValueEx ( key, TEXT("ThemeActive"), 0, REG_SZ, (PBYTE)data, sizeof (data) ); RegCloseKey (key); } } typedef struct { UINT cbSize; SHELLSTATE ss; } REGSHELLSTATE, *PREGSHELLSTATE; VOID SwitchToClassicTaskBar ( IN HINSTANCE Instance, IN HWND hwndDlg, IN PCTSTR Args ) { HKEY key = NULL; DWORD dataType; DWORD dataSize = 0; PBYTE data = NULL; PREGSHELLSTATE shellState = NULL; LONG result; // // The only thing that we need to do is to turn off the fStartPanelOn field in: // HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer [ShellState] // result = RegOpenKeyEx ( HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), 0, KEY_READ | KEY_WRITE, &key ); if ((result == ERROR_SUCCESS) && (key) ) { result = RegQueryValueEx ( key, TEXT ("ShellState"), NULL, &dataType, NULL, &dataSize ); if ((result == ERROR_SUCCESS) || (result == ERROR_MORE_DATA)) { data = (PBYTE) LocalAlloc (LPTR, dataSize); if (data) { result = RegQueryValueEx ( key, TEXT ("ShellState"), NULL, &dataType, data, &dataSize ); if ((result == ERROR_SUCCESS) && (dataType == REG_BINARY) && (dataSize == sizeof (REGSHELLSTATE)) ) { if (dataType == REG_BINARY) { shellState = (PREGSHELLSTATE) data; shellState->ss.fStartPanelOn = FALSE; RegSetValueEx ( key, TEXT("ShellState"), 0, REG_BINARY, (PBYTE)data, dataSize ); } } LocalFree (data); } } RegCloseKey (key); } } VOID RegisterFonts ( IN HINSTANCE Instance, IN HWND hwndDlg, IN PCTSTR Args ) { WIN32_FIND_DATA findData; HANDLE findHandle = INVALID_HANDLE_VALUE; PTSTR fontDir = NULL; TCHAR fontPattern [MAX_PATH]; // // Let's (re)register all the fonts (in case the user migrated some new ones). // fontDir = GetShellFolderPath (CSIDL_FONTS, NULL, TRUE, NULL); if (fontDir) { StrCpyN (fontPattern, fontDir, ARRAYSIZE (fontPattern) - 4); StrCat (fontPattern, TEXT("\\*.*")); findHandle = FindFirstFile (fontPattern, &findData); if (findHandle != INVALID_HANDLE_VALUE) { do { AddFontResource (findData.cFileName); } while (FindNextFile (findHandle, &findData)); FindClose (findHandle); } } } VOID RefreshMetrics ( IN HINSTANCE Instance, IN HWND hwndDlg, IN PCTSTR Args ) { // // Refresh all system metrics // __RefreshMetric (MS_NO_ARG, 0, SPI_SETCURSORS, 0); __RefreshMetric (MS_NO_ARG, 0, SPI_SETDESKPATTERN, 0); __RefreshMetric (MS_MAX_PATH, SPI_GETDESKWALLPAPER, SPI_SETDESKWALLPAPER, 0); __RefreshMetric (MS_BOOL, SPI_GETFONTSMOOTHING, SPI_SETFONTSMOOTHING, 0); __RefreshMetric (MS_RECT, SPI_GETWORKAREA, SPI_SETWORKAREA, 0); __RefreshMetric (MS_BLOB, SPI_GETICONMETRICS, SPI_SETICONMETRICS, sizeof (ICONMETRICS)); __RefreshMetric (MS_NO_ARG, 0, SPI_SETICONS, 0); __RefreshMetric (MS_BLOB, SPI_GETICONTITLELOGFONT, SPI_SETICONTITLELOGFONT, sizeof (LOGFONT)); __RefreshMetric (MS_BOOL, SPI_GETICONTITLEWRAP, SPI_SETICONTITLEWRAP, 0); __RefreshMetric (MS_BOOL, SPI_GETBEEP, SPI_SETBEEP, 0); __RefreshMetric (MS_BOOL, SPI_GETKEYBOARDCUES, SPI_SETKEYBOARDCUES, 0); __RefreshMetric (MS_INT, SPI_GETKEYBOARDDELAY, SPI_SETKEYBOARDDELAY, 0); __RefreshMetric (MS_BOOL, SPI_GETKEYBOARDPREF, SPI_SETKEYBOARDPREF, 0); __RefreshMetric (MS_INT, SPI_GETKEYBOARDSPEED, SPI_SETKEYBOARDSPEED, 0); //__RefreshMetric (MS_BOOL, SPI_GETMOUSEBUTTONSWAP, SPI_SETMOUSEBUTTONSWAP, 0); __RefreshMetric (MS_INT, SPI_GETMOUSEHOVERHEIGHT, SPI_SETMOUSEHOVERHEIGHT, 0); __RefreshMetric (MS_INT, SPI_GETMOUSEHOVERTIME, SPI_SETMOUSEHOVERTIME, 0); __RefreshMetric (MS_INT, SPI_GETMOUSEHOVERWIDTH, SPI_SETMOUSEHOVERWIDTH, 0); __RefreshMetric (MS_INT, SPI_GETMOUSESPEED, SPI_SETMOUSESPEED, 0); __RefreshMetric (MS_INT, SPI_GETMOUSETRAILS, SPI_SETMOUSETRAILS, 0); //__RefreshMetric (MS_INT, SPI_GETDOUBLECLICKTIME, SPI_SETDOUBLECLICKTIME, 0); //__RefreshMetric (MS_INT, SPI_GETDOUBLECLKHEIGHT, SPI_SETDOUBLECLKHEIGHT, 0); //__RefreshMetric (MS_INT, SPI_GETDOUBLECLKWIDTH, SPI_SETDOUBLECLKWIDTH, 0); __RefreshMetric (MS_BOOL, SPI_GETSNAPTODEFBUTTON, SPI_SETSNAPTODEFBUTTON, 0); __RefreshMetric (MS_INT, SPI_GETWHEELSCROLLLINES, SPI_SETWHEELSCROLLLINES, 0); __RefreshMetric (MS_BOOL, SPI_GETMENUDROPALIGNMENT, SPI_SETMENUDROPALIGNMENT, 0); __RefreshMetric (MS_BOOL, SPI_GETMENUFADE, SPI_SETMENUFADE, 0); __RefreshMetric (MS_BOOL, SPI_GETMENUSHOWDELAY, SPI_SETMENUSHOWDELAY, 0); __RefreshMetric (MS_BOOL, SPI_GETLOWPOWERACTIVE, SPI_SETLOWPOWERACTIVE, 0); __RefreshMetric (MS_INT, SPI_GETLOWPOWERTIMEOUT, SPI_SETLOWPOWERTIMEOUT, 0); __RefreshMetric (MS_BOOL, SPI_GETPOWEROFFACTIVE, SPI_SETPOWEROFFACTIVE, 0); __RefreshMetric (MS_INT, SPI_GETPOWEROFFTIMEOUT, SPI_SETPOWEROFFTIMEOUT, 0); __RefreshMetric (MS_BOOL, SPI_GETSCREENSAVEACTIVE, SPI_SETSCREENSAVEACTIVE, 0); __RefreshMetric (MS_INT, SPI_GETSCREENSAVETIMEOUT, SPI_SETSCREENSAVETIMEOUT, 0); __RefreshMetric (MS_BOOL, SPI_GETCOMBOBOXANIMATION, SPI_SETCOMBOBOXANIMATION, 0); __RefreshMetric (MS_BOOL, SPI_GETCURSORSHADOW, SPI_SETCURSORSHADOW, 0); __RefreshMetric (MS_BOOL, SPI_GETGRADIENTCAPTIONS, SPI_SETGRADIENTCAPTIONS, 0); __RefreshMetric (MS_BOOL, SPI_GETHOTTRACKING, SPI_SETHOTTRACKING, 0); __RefreshMetric (MS_BOOL, SPI_GETLISTBOXSMOOTHSCROLLING, SPI_SETLISTBOXSMOOTHSCROLLING, 0); __RefreshMetric (MS_BOOL, SPI_GETSELECTIONFADE, SPI_SETSELECTIONFADE, 0); __RefreshMetric (MS_BOOL, SPI_GETTOOLTIPANIMATION, SPI_SETTOOLTIPANIMATION, 0); __RefreshMetric (MS_BOOL, SPI_GETTOOLTIPFADE, SPI_SETTOOLTIPFADE, 0); __RefreshMetric (MS_BOOL, SPI_GETUIEFFECTS, SPI_SETUIEFFECTS, 0); __RefreshMetric (MS_BOOL, SPI_GETACTIVEWINDOWTRACKING, SPI_SETACTIVEWINDOWTRACKING, 0); __RefreshMetric (MS_BOOL, SPI_GETACTIVEWNDTRKZORDER, SPI_SETACTIVEWNDTRKZORDER, 0); __RefreshMetric (MS_INT, SPI_GETACTIVEWNDTRKTIMEOUT, SPI_SETACTIVEWNDTRKTIMEOUT, 0); __RefreshMetric (MS_BLOB, SPI_GETANIMATION, SPI_SETANIMATION, sizeof (ANIMATIONINFO)); __RefreshMetric (MS_INT, SPI_GETBORDER, SPI_SETBORDER, 0); __RefreshMetric (MS_INT, SPI_GETCARETWIDTH, SPI_SETCARETWIDTH, 0); __RefreshMetric (MS_BOOL, SPI_GETDRAGFULLWINDOWS, SPI_SETDRAGFULLWINDOWS, 0); __RefreshMetric (MS_INT, SPI_GETFOREGROUNDFLASHCOUNT, SPI_SETFOREGROUNDFLASHCOUNT, 0); __RefreshMetric (MS_INT, SPI_GETFOREGROUNDLOCKTIMEOUT, SPI_SETFOREGROUNDLOCKTIMEOUT, 0); __RefreshMetric (MS_BLOB, SPI_GETMINIMIZEDMETRICS, SPI_SETMINIMIZEDMETRICS, sizeof (MINIMIZEDMETRICS)); __RefreshMetric (MS_BLOB, SPI_GETNONCLIENTMETRICS, SPI_SETNONCLIENTMETRICS, sizeof (NONCLIENTMETRICS)); __RefreshMetric (MS_BOOL, SPI_GETSHOWIMEUI, SPI_SETSHOWIMEUI, 0); // SPI_SETMOUSE // SPI_SETDRAGHEIGHT // SPI_SETDRAGWIDTH __RefreshMetric (MS_BLOB, SPI_GETACCESSTIMEOUT, SPI_SETACCESSTIMEOUT, sizeof (ACCESSTIMEOUT)); __RefreshMetric (MS_BLOB, SPI_GETFILTERKEYS, SPI_SETFILTERKEYS, sizeof (FILTERKEYS)); __RefreshMetric (MS_BLOB, SPI_GETHIGHCONTRAST, SPI_SETHIGHCONTRAST, sizeof (HIGHCONTRAST)); __RefreshMetric (MS_BLOB, SPI_GETMOUSEKEYS, SPI_SETMOUSEKEYS, sizeof (MOUSEKEYS)); __RefreshMetric (MS_BLOB, SPI_GETSERIALKEYS, SPI_SETSERIALKEYS, sizeof (SERIALKEYS)); __RefreshMetric (MS_BOOL, SPI_GETSHOWSOUNDS, SPI_SETSHOWSOUNDS, 0); __RefreshMetric (MS_BLOB, SPI_GETSOUNDSENTRY, SPI_SETSOUNDSENTRY, sizeof (SOUNDSENTRY)); __RefreshMetric (MS_BLOB, SPI_GETSTICKYKEYS, SPI_SETSTICKYKEYS, sizeof (STICKYKEYS)); __RefreshMetric (MS_BLOB, SPI_GETTOGGLEKEYS, SPI_SETTOGGLEKEYS, sizeof (TOGGLEKEYS)); } VOID AskForLogOff ( IN HINSTANCE Instance, IN HWND hwndDlg, IN PCTSTR Args ) { g_LogOffSystem = TRUE; } VOID AskForReboot ( IN HINSTANCE Instance, IN HWND hwndDlg, IN PCTSTR Args ) { g_RebootSystem = TRUE; } VOID SaveOFStatus ( IN HINSTANCE Instance, IN HWND hwndDlg, IN PCTSTR Args ) { HKEY key = NULL; LONG lResult; DWORD dataType; DWORD dataSize; DWORD data; lResult = RegOpenKey (HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Applets\\SysTray"), &key); if ((lResult == ERROR_SUCCESS) && key) { dataSize = 0; lResult = RegQueryValueEx (key, TEXT("Services"), NULL, &dataType, NULL, &dataSize); if ((lResult == ERROR_SUCCESS) && (dataType == REG_DWORD)) { lResult = RegQueryValueEx (key, TEXT("Services"), NULL, &dataType, (LPBYTE)(&data), &dataSize); if (lResult == ERROR_SUCCESS) { g_OFStatus = ((data & 0x00000008) != 0); } } CloseHandle (key); } } VOID RebootOnOFStatusChange ( IN HINSTANCE Instance, IN HWND hwndDlg, IN PCTSTR Args ) { HKEY key = NULL; LONG lResult; DWORD dataType; DWORD dataSize; DWORD data; lResult = RegOpenKey (HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Applets\\SysTray"), &key); if ((lResult == ERROR_SUCCESS) && key) { dataSize = 0; lResult = RegQueryValueEx (key, TEXT("Services"), NULL, &dataType, NULL, &dataSize); if ((lResult == ERROR_SUCCESS) && (dataType == REG_DWORD)) { lResult = RegQueryValueEx (key, TEXT("Services"), NULL, &dataType, (LPBYTE)(&data), &dataSize); if (lResult == ERROR_SUCCESS) { if (g_OFStatus && ((data & 0x00000008) == 0)) { AskForReboot (Instance, hwndDlg, NULL); } if ((!g_OFStatus) && ((data & 0x00000008) != 0)) { AskForReboot (Instance, hwndDlg, NULL); } } } CloseHandle (key); } } typedef BOOL (WINAPI LOCKSETFOREGROUNDWINDOW)(UINT uLockCode); typedef LOCKSETFOREGROUNDWINDOW *PLOCKSETFOREGROUNDWINDOW; VOID RestartExplorer ( IN HINSTANCE Instance, IN HWND hwndDlg, IN PCTSTR Args ) { BOOL bResult; STARTUPINFO si; PROCESS_INFORMATION pi; HMODULE lib; PLOCKSETFOREGROUNDWINDOW dynLockSetForegroundWindow; if (g_Explorer) { // // Start explorer.exe // ZeroMemory( &si, sizeof(STARTUPINFO) ); si.cb = sizeof(STARTUPINFO); lib = LoadLibrary (TEXT("user32.dll")); if (lib) { dynLockSetForegroundWindow = (PLOCKSETFOREGROUNDWINDOW) GetProcAddress (lib, "LockSetForegroundWindow"); if (dynLockSetForegroundWindow) { // let's lock this so Explorer does not steal our focus dynLockSetForegroundWindow (LSFW_LOCK); } FreeLibrary (lib); } bResult = CreateProcess( NULL, g_Explorer, NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi ); if (bResult) { CloseHandle (pi.hProcess); CloseHandle (pi.hThread); } } } BOOL AppExecute ( IN HINSTANCE Instance, IN HWND hwndDlg, IN PCTSTR ExecuteArgs ) { PCTSTR funcName = NULL; PCTSTR funcArgs = NULL; funcName = ExecuteArgs; if (!funcName || !(*funcName)) { return FALSE; } funcArgs = StrChrI (funcName, 0); if (funcArgs) { funcArgs ++; if (!(*funcArgs)) { funcArgs = NULL; } } // BUGBUG - temporary, make a macro expansion list out of it if (0 == StrCmpI (funcName, TEXT("KillExplorer"))) { KillExplorer (Instance, hwndDlg, funcArgs); } if (0 == StrCmpI (funcName, TEXT("RefreshMetrics"))) { RefreshMetrics (Instance, hwndDlg, funcArgs); } if (0 == StrCmpI (funcName, TEXT("AskForLogOff"))) { AskForLogOff (Instance, hwndDlg, funcArgs); } if (0 == StrCmpI (funcName, TEXT("AskForReboot"))) { AskForReboot (Instance, hwndDlg, funcArgs); } if (0 == StrCmpI (funcName, TEXT("RestartExplorer"))) { RestartExplorer (Instance, hwndDlg, funcArgs); } if (0 == StrCmpI (funcName, TEXT("SwitchToClassicDesktop"))) { SwitchToClassicDesktop (Instance, hwndDlg, funcArgs); } if (0 == StrCmpI (funcName, TEXT("SwitchToClassicTaskBar"))) { SwitchToClassicTaskBar (Instance, hwndDlg, funcArgs); } if (0 == StrCmpI (funcName, TEXT("RegisterFonts"))) { RegisterFonts (Instance, hwndDlg, funcArgs); } if (0 == StrCmpI (funcName, TEXT("SaveOFStatus"))) { SaveOFStatus (Instance, hwndDlg, funcArgs); } if (0 == StrCmpI (funcName, TEXT("RebootOnOFStatusChange"))) { RebootOnOFStatusChange (Instance, hwndDlg, funcArgs); } return TRUE; } //////////////////////////////////////////////////// // // Obtaining a connection point sink is supposed to be easy. You just // QI for the interface. Unfortunately, too many components are buggy. // // mmc.exe faults if you QI for IDispatch // and punkCB is non-NULL. And if you do pass in NULL, // it returns S_OK but fills punkCB with NULL anyway. // Somebody must've had a rough day. // // Java responds only to its dispatch ID and not IID_IDispatch, even // though the dispatch ID is derived from IID_IDispatch. // // The Explorer Band responds only to IID_IDispatch and not to // the dispatch ID. // HRESULT GetConnectionPointSink(IUnknown *pUnk, const IID *piidCB, IUnknown **ppunkCB) { HRESULT hr = E_NOINTERFACE; *ppunkCB = NULL; // Pre-zero it to work around MMC if (piidCB) // Optional interface (Java/ExplBand) { hr = pUnk->QueryInterface(*piidCB, (void **) ppunkCB); if (*ppunkCB == NULL) // Clean up behind MMC hr = E_NOINTERFACE; } return hr; } // // Enumerate the connection point sinks, calling the callback for each one // found. // // The callback function is called once for each sink. The IUnknown is // whatever interface we could get from the sink (either piidCB or piidCB2). // typedef HRESULT (CALLBACK *ENUMCONNECTIONPOINTSPROC)( /* [in, iid_is(*piidCB)] */ IUnknown *psink, LPARAM lParam); HRESULT EnumConnectionPointSinks( IConnectionPoint *pcp, // IConnectionPoint victim const IID *piidCB, // Interface for callback const IID *piidCB2, // Alternate interface for callback ENUMCONNECTIONPOINTSPROC EnumProc, // Callback procedure LPARAM lParam) // Refdata for callback { HRESULT hr; IEnumConnections * pec; if (pcp) hr = pcp->EnumConnections(&pec); else hr = E_NOINTERFACE; if (SUCCEEDED(hr)) { CONNECTDATA cd; ULONG cFetched; while (S_OK == (hr = pec->Next(1, &cd, &cFetched))) { IUnknown *punkCB; //ASSERT(1 == cFetched); hr = GetConnectionPointSink(cd.pUnk, piidCB, &punkCB); if (FAILED(hr)) hr = GetConnectionPointSink(cd.pUnk, piidCB2, &punkCB); if (SUCCEEDED(hr)) { hr = EnumProc(punkCB, lParam); punkCB->Release(); } else { hr = S_OK; // Pretend callback succeeded } cd.pUnk->Release(); if (FAILED(hr)) break; // Callback asked to stop } pec->Release(); hr = S_OK; } return hr; } // // Send out the callback (if applicable) and then do the invoke if the // callback said that was a good idea. // // Parameters: // // pcp - IConnectionPoint whose sinks are to be Invoke()d. // If this parameter is NULL, the function does nothing. // pinv - Structure containing parameters to INVOKE. HRESULT CALLBACK EnumInvokeCallback(IUnknown *psink, LPARAM lParam) { IDispatch *pdisp = (IDispatch *)psink; LPSHINVOKEPARAMS pinv = (LPSHINVOKEPARAMS)lParam; HRESULT hr; if (pinv->Callback) { // Now see if the callback wants to do pre-vet the pdisp. // It can return S_FALSE to skip this callback or E_FAIL to // stop the invoke altogether hr = pinv->Callback(pdisp, pinv); if (hr != S_OK) return hr; } pdisp->Invoke(pinv->dispidMember, *pinv->piid, pinv->lcid, pinv->wFlags, pinv->pdispparams, pinv->pvarResult, pinv->pexcepinfo, pinv->puArgErr); return S_OK; } // // QI's for IConnectionPointContainer and then does the FindConnectionPoint. // // Parameters: // // punk - The object who might be an IConnectionPointContainer. // This parameter may be NULL, in which case the // operation fails. // riidCP - The connection point interface to locate. // pcpOut - Receives the IConnectionPoint, if any. HRESULT IUnknown_FindConnectionPoint(IUnknown *punk, REFIID riidCP, IConnectionPoint **pcpOut) { HRESULT hr; *pcpOut = NULL; if (punk) { IConnectionPointContainer *pcpc; hr = punk->QueryInterface(IID_IConnectionPointContainer, (void **)&pcpc); if (SUCCEEDED(hr)) { hr = pcpc->FindConnectionPoint(riidCP, pcpOut); pcpc->Release(); } } else hr = E_NOINTERFACE; return hr; } // // IConnectionPoint_InvokeIndirect // // Given a connection point, call the IDispatch::Invoke for each // connected sink. // // The return value merely indicates whether the command was dispatched. // If any particular sink fails the IDispatch::Invoke, we will still // return S_OK, since the command was indeed dispatched. // // Parameters: // // pcp - IConnectionPoint whose sinks are to be Invoke()d. // If this parameter is NULL, the function does nothing. // pinv - Structure containing parameters to INVOKE. // The pdispparams field can be NULL; we will turn it // into a real DISPPARAMS for you. // // The SHINVOKEPARAMS.flags field can contain the following flags. // // IPFL_USECALLBACK - The callback field contains a callback function // Otherwise, it will be set to NULL. // IPFL_USEDEFAULT - Many fields in the SHINVOKEPARAMS will be set to // default values to save the caller effort: // // riid = IID_NULL // lcid = 0 // wFlags = DISPATCH_METHOD // pvarResult = NULL // pexcepinfo = NULL // puArgErr = NULL // HRESULT IConnectionPoint_InvokeIndirect( IConnectionPoint *pcp, SHINVOKEPARAMS *pinv) { HRESULT hr; DISPPARAMS dp = { 0 }; IID iidCP; if (pinv->pdispparams == NULL) pinv->pdispparams = &dp; if (!(pinv->flags & IPFL_USECALLBACK)) { pinv->Callback = NULL; } if (pinv->flags & IPFL_USEDEFAULTS) { pinv->piid = &IID_NULL; pinv->lcid = 0; pinv->wFlags = DISPATCH_METHOD; pinv->pvarResult = NULL; pinv->pexcepinfo = NULL; pinv->puArgErr = NULL; } // Try both the interface they actually connected on, // as well as IDispatch. Apparently Java responds only to // the connecting interface, and ExplBand responds only to // IDispatch, so we have to try both. (Sigh. Too many buggy // components in the system.) hr = EnumConnectionPointSinks(pcp, (pcp->GetConnectionInterface(&iidCP) == S_OK) ? &iidCP : NULL, &IID_IDispatch, EnumInvokeCallback, (LPARAM)pinv); // Put the original NULL back so the caller can re-use the SHINVOKEPARAMS. if (pinv->pdispparams == &dp) pinv->pdispparams = NULL; return hr; } // // Given an IUnknown, query for its connection point container, // find the corresponding connection point, package up the // invoke parameters, and call the IDispatch::Invoke for each // connected sink. // // See IConnectionPoint_InvokeParam for additional semantics. // // Parameters: // // punk - Object that might be an IConnectionPointContainer // riidCP - ConnectionPoint interface to request // pinv - Arguments for the Invoke. // HRESULT IUnknown_CPContainerInvokeIndirect(IUnknown *punk, REFIID riidCP, SHINVOKEPARAMS *pinv) { IConnectionPoint *pcp; HRESULT hr = IUnknown_FindConnectionPoint(punk, riidCP, &pcp); if (SUCCEEDED(hr)) { hr = IConnectionPoint_InvokeIndirect(pcp, pinv); pcp->Release(); } return hr; } ////////////////////////////////////////////////////////////////////////////////////// VOID _UpdateText( IN HWND hWnd, IN LPCTSTR pcszString ) { TCHAR szCurString[MAX_LOADSTRING]; if (pcszString) { SendMessage (hWnd, WM_GETTEXT, (WPARAM)MAX_LOADSTRING, (LPARAM)szCurString); if (StrCmp (pcszString, szCurString)) { SendMessage (hWnd, WM_SETTEXT, 0, (LPARAM)pcszString); } } } ////////////////////////////////////////////////////////////////////////////////////// VOID _RemoveSpaces ( IN PTSTR szData, IN UINT uDataCount ) { UINT curr; PTSTR currPtr; PTSTR lastSpace; BOOL isSpace; // First trim the spaces at the beginning if (!szData) { return; } curr = _tcsnextc (szData); while (curr == TEXT(' ')) { currPtr = _tcsinc (szData); memmove (szData, currPtr, uDataCount * sizeof(TCHAR) - (UINT)((currPtr - szData) * sizeof (TCHAR))); curr = _tcsnextc (szData); } // Now trim the trailing spaces lastSpace = NULL; currPtr = szData; curr = _tcsnextc (szData); while (curr) { if (curr == TEXT(' ')) { if (!lastSpace) { lastSpace = currPtr; } } else { if (lastSpace) { lastSpace = NULL; } } currPtr = _tcsinc (currPtr); curr = _tcsnextc (currPtr); } if (lastSpace) { *lastSpace = 0; } } POBJLIST _AllocateObjectList ( IN PCTSTR ObjectName ) { POBJLIST objList; objList = (POBJLIST)LocalAlloc (LPTR, sizeof (OBJLIST)); if (objList) { ZeroMemory (objList, sizeof (OBJLIST)); objList->ObjectName = (PTSTR)LocalAlloc (LPTR, (_tcslen (ObjectName) + 1) * sizeof (TCHAR)); if (objList->ObjectName) { _tcscpy (objList->ObjectName, ObjectName); } } return objList; } VOID pFreeObjects ( IN POBJLIST ObjectList ) { if (ObjectList->Next) { pFreeObjects(ObjectList->Next); LocalFree(ObjectList->Next); ObjectList->Next = NULL; } if (ObjectList->ObjectName) { LocalFree(ObjectList->ObjectName); ObjectList->ObjectName = NULL; } } VOID _FreeObjectList ( IN POBJLIST ObjectList ) { if (ObjectList) { pFreeObjects(ObjectList); LocalFree(ObjectList); } }