|
|
/****************************************************************************\
MISCAPI.C / OPK Wizard (OPKWIZ.EXE)
Microsoft Confidential Copyright (c) Microsoft Corporation 1999 All rights reserved
Misc. API source file for generic APIs used in the OPK Wizard.
4/99 - Jason Cohen (JCOHEN) Added this new source file for the OPK Wizard as part of the Millennium rewrite. 09/2000 - Stephen Lodwick (STELO) Ported OPK Wizard to Whistler
\****************************************************************************/
//
// Include file(s)
//
#include "pch.h"
#include "resource.h"
//
// Internal Defined Value(s):
//
#define STR_URLDEF _T("http://")
#define STR_EVENT_CANCEL _T("SETUPMGR_EVENT_CANCEL")
//
// Internal Defined Macro(s):
//
#define MALLOC(cb) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb)
#define FREE(lp) ( (lp != NULL) ? ( (HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, (LPVOID) lp)) ? ((lp = NULL) == NULL) : (FALSE) ) : (FALSE) )
//
// Internal Type Definition(s):
//
typedef struct _COPYDIRDATA { HWND hwndParent; LPTSTR lpSrc; LPTSTR lpDst; HANDLE hEvent; } COPYDIRDATA, *PCOPYDIRDATA, *LPCOPYDIRDATA;
//
// Internal Function Prototype(s):
//
LRESULT CALLBACK CopyDirDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); DWORD WINAPI CopyDirThread(LPVOID lpVoid);
//
// External Function(s):
//
// If we find a key name with _Gray then *pfGray == TRUE
//
void ReadInstallInsKey(TCHAR szSection[], TCHAR szKey[], TCHAR szValue[], INT cchValue, TCHAR szIniFile[], BOOL* pfGray) { TCHAR szTempKey[MAX_PATH]; HRESULT hrCat;
if (!pfGray) return;
lstrcpyn(szTempKey, szKey, AS(szTempKey)); if (!OpkGetPrivateProfileString(szSection, szTempKey, szValue, szValue, cchValue, szIniFile)) { hrCat=StringCchCat(szTempKey, AS(szTempKey), GRAY); if (OpkGetPrivateProfileString(szSection, szTempKey, szValue, szValue, cchValue, szIniFile)) *pfGray = TRUE; else *pfGray = TRUE; // default to unchecked if not found!
} else *pfGray = FALSE; }
// If pfGrayed == TRUE then concatenate _Gray to the key name
//
void WriteInstallInsKey(TCHAR szSection[], TCHAR szKey[], TCHAR szValue[], TCHAR szIniFile[], BOOL fGrayed) { TCHAR szKeyTemp[MAX_PATH]; HRESULT hrCat;
// Clear the old value
//
lstrcpyn(szKeyTemp, szKey, AS(szKeyTemp)); OpkWritePrivateProfileString(szSection, szKeyTemp, NULL, szIniFile); hrCat=StringCchCat(szKeyTemp, AS(szKeyTemp), GRAY); OpkWritePrivateProfileString(szSection, szKeyTemp, NULL, szIniFile);
// Write the new value
lstrcpyn(szKeyTemp, szKey, AS(szKeyTemp)); if (fGrayed) hrCat=StringCchCat(szKeyTemp, AS(szKeyTemp), GRAY); OpkWritePrivateProfileString(szSection, szKeyTemp, szValue, szIniFile); }
// NOTE: pszFileName must point to buffer at least length MAX_PATH
void CheckValidBrowseFolder(TCHAR* pszFileName) { if (NULL == pszFileName) return;
// Last known good browse start folder
//
PathRemoveFileSpec(pszFileName); if (!lstrlen(pszFileName)) lstrcpyn(pszFileName, g_App.szLastKnownBrowseFolder, MAX_PATH); }
void SetLastKnownBrowseFolder(TCHAR* pszFileName) { if (NULL == pszFileName) return;
// Save Last known good browse start folder
//
PathCombine(g_App.szLastKnownBrowseFolder, pszFileName, NULL); PathRemoveFileSpec(g_App.szLastKnownBrowseFolder); }
// NOTE: lpszURL is assumed to point to a buffer at least MAX_URL in length
BOOL ValidURL(LPTSTR lpszURL) { BOOL bResult = TRUE; TCHAR szBuffer[MAX_PATH] = NULLSTR; HRESULT hrCat;
// Check if valid URL
//
if ( !PathIsURL(lpszURL) ) { // Check if empty string first
//
if (0 == lstrlen(lpszURL)) bResult = FALSE; else { // Currently not a valid URL, we are now going to prepend the
// URL with http:// and then test the validity again
//
lstrcpyn(szBuffer, STR_URLDEF, AS(szBuffer)); hrCat=StringCchCat(szBuffer, AS(szBuffer), lpszURL); // Still not a valid URL or we were unable to copy the string
//
if ( !PathIsURL(szBuffer) || !lstrcpyn(lpszURL, szBuffer, MAX_URL) ) bResult = FALSE; } }
return bResult;
}
BOOL IsFolderShared(LPWSTR lpFolder, LPWSTR lpShare, DWORD cbShare) { LPSHARE_INFO_502 lpsi502 = NULL; DWORD dwRead = 0, dwTotal = 0; NET_API_STATUS nas; BOOL bRet = FALSE, bBest = FALSE, bBuffer = ( lpShare && cbShare ); PACL paclOld = NULL; TCHAR szUnc[MAX_COMPUTERNAME_LENGTH + 4] = NULLSTR;
// Success or failure, we will always atleast pass back the computer
// name if they passed in a buffer. So here is where we create the
// computer name part of the path.
//
if ( bBuffer ) { DWORD cbUnc = AS(szUnc) - 2; HRESULT hrCat;
// We want to return the UNC path, so first need the \\ plus the
// computer name.
//
// NOTE: We hard coded the length of the "\\" string below as 2
// in two different places. Once just above, and once below
// in the GetComputerName() call. We also hard code the "\"
// string below as 1 when adding to the lenght of the string
// after adding the computer name. So don't forget these things
// if you make some changes here.
//
lstrcpyn(szUnc, _T("\\\\"), cbUnc); if ( ( GetComputerName(szUnc + 2, &cbUnc) ) && ( AS(szUnc) > ((DWORD) lstrlen(szUnc) + 1) ) ) { // Added on a backslash so we can add the share name.
//
hrCat=StringCchCat(szUnc,AS(szUnc), _T("\\")); } else { // If GetComputerName() fails, that is bad. But we will just
// return the share name. That is about all we can do.
//
szUnc[0] = NULLCHR; }
} // Now share time, first retrieve all the shares on this machine.
//
nas = NetShareEnum(NULL, 502, (unsigned char **) &lpsi502, MAX_PREFERRED_LENGTH, &dwRead, &dwTotal, NULL);
// Make sure we got a list of shares, otherwise there is nothing.
// we can do. Because we specify MAX_PREFERRED_LENGTH, we should
// never get ERROR_MORE_DATA, but if for some reason we do there is
// no reason not to loop through the ones we did get.
//
if ( ( lpsi502 ) && ( ( nas == NERR_Success ) || ( nas == ERROR_MORE_DATA ) ) ) { int iLength = lstrlen(lpFolder); LPTSTR lpSearch = lpFolder + iLength; HRESULT hrCat;
// Trailing backslash is only bad if not the root folder.
//
if ( iLength > 3 ) { // See if the folder has a trailing backslash.
//
lpSearch = CharPrev(lpFolder, lpSearch); if ( *lpSearch == _T('\\') ) { iLength--; } }
// Go through all the shares until we fine the best
// one for this directory.
//
while ( dwRead-- && !bBest ) { // See if this share is a disk share and is the
// same path passed in.
//
if ( ( lpsi502[dwRead].shi502_type == STYPE_DISKTREE ) && ( StrCmpNI(lpsi502[dwRead].shi502_path, lpFolder, iLength) == 0 ) && ( lstrlen(lpsi502[dwRead].shi502_path) == iLength ) ) { // If this directory is shared more than once, we want to use
// the first one we fine with no security descriptor, because
// then it is most likely shared out to everyone.
//
if ( lpsi502[dwRead].shi502_security_descriptor == NULL ) { // If there is no security descriptor, then everyone should have
// access and this is a good share.
//
bBest = TRUE; }
// If we have no ACL, or we reset it because the new one is better,
// then we want to copy off the share name into our return buffer.
//
if ( !bRet || bBest ) { // Return the share name for this directory in the supplied buffer
// (if the buffer is NULL or zero size, we just return TRUE so they
// know that the folder is shared even if they don't care what the
// name of the share is).
//
if ( bBuffer ) { // Find out what we have room for in the return buffer.
//
if ( cbShare > (DWORD) (lstrlen(lpsi502[dwRead].shi502_netname) + lstrlen(szUnc)) ) { // Copy the computer name and share into return buffer.
//
lstrcpyn(lpShare, szUnc, cbShare); hrCat=StringCchCat(lpShare, cbShare, lpsi502[dwRead].shi502_netname); } else if ( cbShare > (DWORD) lstrlen(lpsi502[dwRead].shi502_netname) ) { // Return buffer not big enough for both computer name and
// share name, so just return the share name.
//
lstrcpyn(lpShare, lpsi502[dwRead].shi502_netname,cbShare); } else { // Not big enough for both, so return TRUE because we found a
// share, but don't return anything in the buffer.
//
*lpShare = NULLCHR; } } }
// We found one, so always set this to TRUE.
//
bRet = TRUE; } } }
// Make sure and free the buffer returned by NetShareEnum().
//
if ( lpsi502 ) NetApiBufferFree(lpsi502);
// Now check to see if we didn't find the share, because we can
// still just return the computer name.
//
if ( ( !bRet && bBuffer ) && ( cbShare > (DWORD) lstrlen(szUnc) ) ) { lstrcpyn(lpShare, szUnc, cbShare); }
return bRet; }
BOOL CopyDirectoryDialog(HINSTANCE hInstance, HWND hwnd, LPTSTR lpSrc, LPTSTR lpDst) { COPYDIRDATA cdd;
// Pass in via the structure the source and destination the dialog needs
// to know about.
//
cdd.lpSrc = lpSrc; cdd.lpDst = lpDst;
// Create the progress dialog.
//
return ( DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PROGRESS), hwnd, CopyDirDlgProc, (LPARAM) &cdd) != 0 ); }
BOOL CopyResetFileErr(HWND hwnd, LPCTSTR lpSource, LPCTSTR lpTarget) { BOOL bReturn;
if ( !(bReturn = CopyResetFile(lpSource, lpTarget)) && hwnd ) MsgBox(hwnd, IDS_MISSINGFILE, IDS_APPNAME, MB_ERRORBOX, lpSource); return bReturn; }
//
// Internal Function(s):
//
LRESULT CALLBACK CopyDirDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static LPCOPYDIRDATA lpcdd = NULL;
switch (uMsg) { case WM_INITDIALOG:
// Make sure we have out copy directory data structure.
//
if ( lParam ) { HANDLE hThread; DWORD dwThreadId;
// Save off our lParam.
//
lpcdd = (LPCOPYDIRDATA) lParam;
// Replace the old parent with the new progress dialog parent.
//
lpcdd->hwndParent = hwnd;
// Need to pass in the cancel event as well.
//
lpcdd->hEvent = CreateEvent(NULL, TRUE, FALSE, STR_EVENT_CANCEL);
// Now create the thread that will copy the actual files.
//
if ( hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) CopyDirThread, (LPVOID) lpcdd, 0, &dwThreadId) ) CloseHandle(hThread); else EndDialog(hwnd, 0); } else EndDialog(hwnd, 0);
return FALSE;
case WM_COMMAND: case WM_CLOSE:
// If we have an event, signal it, or just end the dialog.
//
if ( lpcdd && lpcdd->hEvent ) SetEvent(lpcdd->hEvent); else EndDialog(hwnd, 0); return FALSE;
case WM_DESTROY:
// If there is an event, get rid of it.
//
if ( lpcdd && lpcdd->hEvent ) { CloseHandle(lpcdd->hEvent); lpcdd->hEvent = NULL; } return FALSE;
default: return FALSE; }
return TRUE; }
DWORD WINAPI CopyDirThread(LPVOID lpVoid) { LPCOPYDIRDATA lpcdd = (LPCOPYDIRDATA) lpVoid; HWND hwnd = lpcdd->hwndParent, hwndProgress = GetDlgItem(hwnd, IDC_PROGRESS); HANDLE hEvent = lpcdd->hEvent; DWORD dwRet = 0; LPTSTR lpSrc = lpcdd->lpSrc, lpDst = lpcdd->lpDst;
// First we need to create the path.
//
if ( CreatePath(lpDst) ) { // Setup the progress bar.
//
SendMessage(hwndProgress, PBM_SETSTEP, 1, 0L); SendMessage(hwndProgress, PBM_SETRANGE32, 0, (LPARAM) FileCount(lpSrc));
// Now copy the directory.
//
if ( CopyDirectoryProgressCancel(hwndProgress, hEvent, lpSrc, lpDst) ) dwRet = 1; }
// Now end the dialog with our error code and return.
//
EndDialog(hwnd, dwRet); return dwRet; }
|