|
|
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
upgwiz.c
Abstract:
Implements a stub tool that is designed to run with Win9x-side upgrade code.
Author:
<full name> (<alias>) <date>
Revision History:
ovidiut 01/14/99 Reverted calls to underlying libs in pCallEntryPoints () when Reason == DLL_PROCESS_DETACH
--*/
#include "pch.h"
typedef UINT (GIVEVERSION_PROTOTYPE) (VOID); typedef GIVEVERSION_PROTOTYPE * GIVEVERSION; typedef PDATATYPE (GIVEDATATYPELIST_PROTOTYPE)(PUINT Count); typedef BOOL (GATHERINFOUI_PROTOTYPE)(HINSTANCE LocalDllInstance, UINT DataTypeId); typedef GATHERINFOUI_PROTOTYPE * GATHERINFOUI; typedef GIVEDATATYPELIST_PROTOTYPE * GIVEDATATYPELIST; typedef PDATAOBJECT (GIVEDATAOBJECTLIST_PROTOTYPE)(UINT DataTypeId, PUINT Count); typedef GIVEDATAOBJECTLIST_PROTOTYPE * GIVEDATAOBJECTLIST; typedef BOOL (HANDLE_RMOUSE_PROTOTYPE)(HINSTANCE LocalDllInstance, HWND Owner, PDATAOBJECT DataObject, PPOINT pt); typedef HANDLE_RMOUSE_PROTOTYPE * HANDLE_RMOUSE; typedef BOOL (DISPLAYOPTIONALUI_PROTOTYPE)(POUTPUTARGS Args); typedef DISPLAYOPTIONALUI_PROTOTYPE * DISPLAYOPTIONALUI; typedef BOOL (GENERATEOUTPUT_PROTOTYPE)(POUTPUTARGS Args); typedef GENERATEOUTPUT_PROTOTYPE * GENERATEOUTPUT;
typedef VOID (WIZTOOLSMAIN_PROTOTYPE)(DWORD Reason); typedef WIZTOOLSMAIN_PROTOTYPE * WIZTOOLSMAIN;
typedef struct { UINT Selection; PDATATYPE *DataTypePtrs; UINT PtrCount; BOOL NoSave; } SELECTDATAARGS, *PSELECTDATAARGS;
typedef struct { PDATAOBJECT DataObjectArray; UINT ArraySize; PCSTR Name; BOOL SelectOneOnly; PBOOL StartOverFlag; } SELECTOBJECTSARGS, *PSELECTOBJECTSARGS;
typedef struct { PCSTR TextTitle; PCSTR DescTitle; PCSTR *NewText; PCSTR *NewDesc; UINT MaxSize; PCSTR DataTypeName; PCSTR DataObjectName; BOOL NoDesc; BOOL ReqDesc; BOOL NoText; BOOL ReqText; PBOOL StartOverFlag; } SUPPLYTEXTARGS, *PSUPPLYTEXTARGS;
typedef struct { HANDLE Library; GIVEVERSION GiveVersion; GIVEDATATYPELIST GiveDataTypeList; GATHERINFOUI GatherInfoUI; GIVEDATAOBJECTLIST GiveDataObjectList; HANDLE_RMOUSE Handle_RMouse; DISPLAYOPTIONALUI DisplayOptionalUI; GENERATEOUTPUT GenerateOutput; PDATATYPE DataTypes; UINT DataTypeCount; PDATAOBJECT DataObjects; UINT DataObjectCount; } DGDLL, *PDGDLL;
UINT g_Selections; CHAR g_Msg[2048]; PCSTR g_DataPath = "\\\\popcorn\\public\\win9xupg"; GROWBUFFER g_DllList; POOLHANDLE g_DllListData; PCSTR g_SrcInfPath = NULL; PCSTR g_DestPath = NULL; static CHAR g_ModulePath[MAX_MBCHAR_PATH]; static CHAR g_CleanThisDir[MAX_MBCHAR_PATH]; BOOL g_DontSave; PDGDLL g_CurrentDll = NULL;
WIZTOOLSMAIN g_WizToolsMainProc = NULL;
UINT pSelectDataType ( IN PDATATYPE *DataTypePtrs, IN UINT PtrCount, OUT PBOOL DontSave );
BOOL pSelectDataObjects ( IN OUT PDATAOBJECT DataObjectArray, IN UINT ArraySize, IN PDATATYPE DataType, OUT PBOOL StartOverFlag );
BOOL pGetOptionalText ( IN PCSTR TextTitle, OPTIONAL IN PCSTR DescTitle, OPTIONAL IN PCSTR *NewDesc, IN PCSTR *Buffer, IN UINT MaxSize, IN PDATATYPE DataType, IN PDATAOBJECT DataObject, OPTIONAL OUT PBOOL StartOverFlag );
VOID pThankYouBox ( IN PBOOL StartOverFlag );
VOID pFreeDllList ( IN OUT PGROWBUFFER List, IN POOLHANDLE Buffer );
HANDLE g_hHeap; HINSTANCE g_hInst; PSTR g_WinDir;
BOOL WINAPI MemDb_Entry (HINSTANCE, DWORD, PVOID); BOOL WINAPI MigUtil_Entry (HINSTANCE, DWORD, PVOID); BOOL WINAPI FileEnum_Entry (HINSTANCE, DWORD, PVOID);
BOOL pCallEntryPoints ( DWORD Reason ) { HINSTANCE Instance; static CHAR WinDir[MAX_PATH];
GetWindowsDirectory (WinDir, MAX_PATH); g_WinDir = WinDir;
//
// Simulate DllMain
//
Instance = g_hInst;
//
// Initialize the common libs
//
if (Reason == DLL_PROCESS_ATTACH) {
if (!MigUtil_Entry (Instance, Reason, NULL)) { return FALSE; }
if (!MemDb_Entry (Instance, Reason, NULL)) { return FALSE; }
if (!FileEnum_Entry (Instance, Reason, NULL)) { return FALSE; } } else if (Reason == DLL_PROCESS_DETACH) {
if (!FileEnum_Entry (Instance, Reason, NULL)) { return FALSE; }
if (!MemDb_Entry (Instance, Reason, NULL)) { return FALSE; }
if (!MigUtil_Entry (Instance, Reason, NULL)) { return FALSE; } }
return TRUE; }
BOOL CALLBACK pSetDefGuiFontProc( IN HWND hwnd, IN LPARAM lParam) { SendMessage(hwnd, WM_SETFONT, lParam, 0L); return TRUE; }
void pSetDefGUIFont( IN HWND hdlg ) { EnumChildWindows(hdlg, pSetDefGuiFontProc, (LPARAM)GetStockObject(DEFAULT_GUI_FONT)); }
BOOL Init ( VOID ) { g_hHeap = GetProcessHeap(); g_hInst = GetModuleHandle (NULL);
return pCallEntryPoints (DLL_PROCESS_ATTACH); }
VOID Terminate ( VOID ) { if (g_CleanThisDir[0]) { DeleteDirectoryContents (g_CleanThisDir); RemoveDirectory (g_CleanThisDir); }
pCallEntryPoints (DLL_PROCESS_DETACH); }
BOOL pLoadDataGatherDlls ( BOOL FirstTimeInit, BOOL Local );
VOID pTryToLoadNewUpgWiz ( VOID );
BOOL pDoTheWizard ( VOID );
VOID HelpAndExit ( VOID ) { printf ("Command Line Syntax:\n\n" "upgwiz [-l] [-n:path] [-i:src_inf_path] [-d:path]\n\n" "-l Specifies local mode\n" "-n Specifies network path\n" "-i Specifies the source INF path\n" "-d Specifies destination path\n" );
exit(1); }
INT __cdecl main ( INT argc, CHAR *argv[] ) { CHAR ModulePath[MAX_MBCHAR_PATH]; BOOL Local = FALSE; INT i; PSTR p; BOOL Loop; BOOL FirstTimeInit = TRUE;
if (!Init()) { printf ("Unable to initialize!\n"); return 255; }
GetCurrentDirectory (MAX_MBCHAR_PATH, ModulePath);
GetModuleFileName (g_hInst, g_ModulePath, MAX_MBCHAR_PATH); p = _mbsrchr (g_ModulePath, '\\'); *p = 0;
wsprintf (ModulePath, TEXT("%s\\wiztools.dll"), g_ModulePath); if (DoesFileExist (ModulePath)) { Local = TRUE; }
if (GetDriveType (g_ModulePath) == DRIVE_REMOVABLE) { Local = TRUE; }
if (StringIMatch (g_ModulePath, g_DataPath)) { wsprintf (g_Msg, "This tool cannot be run from %s.", g_DataPath); MessageBox (NULL, g_Msg, NULL, MB_OK); return 255; }
for (i = 1 ; i < argc ; i++) { if (argv[i][0] == '-' || argv[i][0] == '/') { switch (tolower (argv[i][1])) {
case 'l': Local = TRUE; g_DataPath = g_ModulePath; break;
case 'n': if (argv[i][2] == ':') { g_DataPath = &argv[i][3]; } else if (i + 1 < argc) { g_DataPath = argv[i + 1]; } else { HelpAndExit(); }
if (!DoesFileExist (g_DataPath)) { printf ("Can't access %s\n", g_DataPath); exit (2); } break;
case 'i': if (argv[i][2] == ':') { g_SrcInfPath = &argv[i][3]; } else if (i + 1 < argc) { g_SrcInfPath = argv[i + 1]; } else { HelpAndExit(); }
if (!DoesFileExist (g_SrcInfPath)) { printf ("Can't access %s\n", g_SrcInfPath); exit (2); } break;
case 'd': if (argv[i][2] == ':') { g_DestPath = &argv[i][3]; } else if (i + 1 < argc) { g_DestPath = argv[i + 1]; } else { HelpAndExit(); }
if (!DoesFileExist (g_DestPath)) { printf ("Can't access %s\n", g_DestPath); exit (2); } break;
default: HelpAndExit();
} } else { HelpAndExit(); } }
if (!g_SrcInfPath) { g_SrcInfPath = g_DataPath; }
if (!g_DestPath) { g_DestPath = g_DataPath; }
printf ("Src Path: %s\n", g_SrcInfPath); printf ("Dest Path: %s\n", g_DestPath);
Loop = FALSE;
do { if (!pLoadDataGatherDlls (FirstTimeInit, Local)) { wsprintf (g_Msg, "Can't load any DLLs from %s.", g_DataPath); MessageBox (NULL, g_Msg, NULL, MB_OK); } else { FirstTimeInit = FALSE; Loop = pDoTheWizard(); } } while (Loop);
Terminate();
if (g_WizToolsMainProc) { g_WizToolsMainProc (DLL_PROCESS_DETACH); }
return 0; }
VOID pCreateDllList ( OUT PGROWBUFFER List, OUT POOLHANDLE *Buffer ) { ZeroMemory (List, sizeof (GROWBUFFER)); *Buffer = PoolMemInitNamedPool ("DLL List"); }
BOOL pCopyBinaryToTemp ( IN PCSTR DllPath, OUT PSTR TempPath ) { if (!g_CleanThisDir[0]) { StringCopy (TempPath, g_WinDir); StringCopy (AppendWack (TempPath), "upgwiz");
MakeSurePathExists (TempPath, TRUE);
StringCopy (g_CleanThisDir, TempPath); } else { StringCopy (TempPath, g_CleanThisDir); }
StringCopy (AppendWack (TempPath), GetFileNameFromPath (DllPath));
if (DoesFileExist (TempPath)) { return TRUE; }
if (!CopyFile (DllPath, TempPath, FALSE)) { wsprintf ( g_Msg, "Can't copy %s to %s. If the network is working fine, the file " "may already have been copied and is running already, or you " "may need to update your copy of upgwiz.exe.", DllPath, TempPath );
MessageBox (NULL, g_Msg, NULL, MB_OK); return FALSE; } else { printf ("%s copied to %s\n", DllPath, TempPath); }
return TRUE; }
BOOL pPutDllInList ( IN OUT PGROWBUFFER List, IN OUT POOLHANDLE Buffer, IN PCSTR DllPath ) { DGDLL Dll; PDGDLL FinalDll; BOOL b = FALSE; CHAR TempPath[MAX_MBCHAR_PATH];
ZeroMemory (&Dll, sizeof (Dll));
__try { pCopyBinaryToTemp (DllPath, TempPath);
Dll.Library = LoadLibraryEx (TempPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (!Dll.Library) { DWORD rc;
rc = GetLastError(); __leave; }
Dll.GiveVersion = (GIVEVERSION) GetProcAddress (Dll.Library, "GiveVersion"); Dll.GiveDataTypeList = (GIVEDATATYPELIST) GetProcAddress (Dll.Library, "GiveDataTypeList"); Dll.GatherInfoUI = (GATHERINFOUI) GetProcAddress (Dll.Library, "GatherInfoUI"); Dll.GiveDataObjectList = (GIVEDATAOBJECTLIST) GetProcAddress (Dll.Library, "GiveDataObjectList"); Dll.Handle_RMouse = (HANDLE_RMOUSE) GetProcAddress (Dll.Library, "Handle_RMouse"); Dll.DisplayOptionalUI = (DISPLAYOPTIONALUI) GetProcAddress (Dll.Library, "DisplayOptionalUI"); Dll.GenerateOutput = (GENERATEOUTPUT) GetProcAddress (Dll.Library, "GenerateOutput");
if (!Dll.GiveVersion || !Dll.GiveDataTypeList || !Dll.GiveDataObjectList || !Dll.GenerateOutput ) { __leave; }
if (Dll.GiveVersion() != UPGWIZ_VERSION) { __leave; }
b = TRUE; } __finally { if (!b) { if (Dll.Library) { FreeLibrary (Dll.Library); } } }
if (b) { FinalDll = (PDGDLL) GrowBuffer (List, sizeof (DGDLL)); CopyMemory (FinalDll, &Dll, sizeof (Dll)); }
return b; }
VOID pFreeDllList ( IN OUT PGROWBUFFER List, IN POOLHANDLE Buffer ) { UINT Count; PDGDLL Dll;
Dll = (PDGDLL) List->Buf; Count = List->End / sizeof (DGDLL);
while (Count > 0) { Count--; FreeLibrary (Dll->Library); Dll++; }
FreeGrowBuffer (List); PoolMemDestroyPool (Buffer); }
BOOL pLoadDataGatherDlls ( BOOL FirstTimeInit, BOOL Local ) { FILE_ENUM e; BOOL b = FALSE; CHAR HelperBin[MAX_MBCHAR_PATH]; CHAR TempPath[MAX_MBCHAR_PATH]; HINSTANCE Library; CHAR wiztoolsPath[MAX_MBCHAR_PATH];
if (Local || !DoesFileExist (g_DataPath)) {
g_DataPath = g_ModulePath;
}
pCreateDllList (&g_DllList, &g_DllListData);
wsprintf (wiztoolsPath, "%s\\wiztools.dll", g_DataPath);
if (!Local) { //
// Copy everything that is needed to run this app
//
wsprintf (HelperBin, "%s\\msvcrt.dll", g_DataPath); pCopyBinaryToTemp (HelperBin, TempPath);
wsprintf (HelperBin, "%s\\twid.exe", g_DataPath); pCopyBinaryToTemp (HelperBin, TempPath);
wsprintf (HelperBin, "%s\\setupapi.dll", g_DataPath); pCopyBinaryToTemp (HelperBin, TempPath);
wsprintf (HelperBin, "%s\\cfgmgr32.dll", g_DataPath); pCopyBinaryToTemp (HelperBin, TempPath);
wsprintf (HelperBin, "%s\\imagehlp.dll", g_DataPath); pCopyBinaryToTemp (HelperBin, TempPath);
wsprintf (HelperBin, "%s\\wiztools.dll", g_DataPath); pCopyBinaryToTemp (HelperBin, TempPath); StringCopy (wiztoolsPath, TempPath); }
if (FirstTimeInit) { Library = LoadLibraryEx (wiztoolsPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
g_WizToolsMainProc = (WIZTOOLSMAIN) GetProcAddress (Library, "WizToolsMain");
if (g_WizToolsMainProc) { g_WizToolsMainProc (DLL_PROCESS_ATTACH); } }
if (EnumFirstFile (&e, g_DataPath, "*.dll")) { do { if (StringIMatch (e.FileName, "setupapi.dll") || StringIMatch (e.FileName, "cfgmgr32.dll") || StringIMatch (e.FileName, "wiztools.dll") || StringIMatch (e.FileName, "msvcrt.dll") || StringIMatch (e.FileName, "imagehlp.dll") ) { continue; }
if (pPutDllInList (&g_DllList, g_DllListData, e.FullPath)) { b = TRUE; } } while (EnumNextFile (&e)); }
if (!b) { pFreeDllList (&g_DllList, g_DllListData); g_DllListData = NULL; }
return b; }
VOID pTryToLoadNewUpgWiz ( VOID ) { CHAR TempExe[MAX_MBCHAR_PATH]; CHAR PopcornExe[MAX_MBCHAR_PATH]; STARTUPINFO si; PROCESS_INFORMATION pi;
StringCopy (PopcornExe, g_DataPath); StringCopy (AppendWack (PopcornExe), "upgwiz.exe");
if (!pCopyBinaryToTemp (PopcornExe, TempExe)) { return; }
ZeroMemory (&si, sizeof (si)); si.cb = sizeof (si); si.dwFlags = STARTF_FORCEOFFFEEDBACK;
CreateProcessA ( NULL, TempExe, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, g_DataPath, &si, &pi ); }
BOOL pDoTheWizard ( VOID ) { GROWBUFFER DataTypes = GROWBUF_INIT; UINT Count; UINT Pos; PDGDLL Dll; PDATATYPE DataTypeList; PDATATYPE *Ptr; PDATAOBJECT DataObjectList; UINT DataObjectCount; UINT DataTypeListSize; UINT u; OUTPUTARGS Args; PDATAOBJECT SelectedDataObject; BOOL StartOverFlag = FALSE; BOOL Saved;
ZeroMemory (&Args, sizeof (Args));
Dll = (PDGDLL) g_DllList.Buf; Count = g_DllList.End / sizeof (DGDLL);
for (Pos = 0 ; Pos < Count ; Pos++) { DataTypeListSize = 0;
DataTypeList = Dll[Pos].GiveDataTypeList (&DataTypeListSize);
if (!DataTypeList) { DataTypeListSize = 0; }
for (u = 0 ; u < DataTypeListSize ; u++) { Ptr = (PDATATYPE *) GrowBuffer (&DataTypes, sizeof (PDATATYPE)); *Ptr = &DataTypeList[u]; (*Ptr)->Reserved = (PVOID) Pos; } }
if (DataTypes.End == 0) { MessageBox (NULL, "No data type DLLs to select from. There may be network access problems.", NULL, MB_OK); return FALSE; }
__try {
//
// User selects data type
//
Pos = pSelectDataType ((PDATATYPE *) DataTypes.Buf, DataTypes.End / sizeof (PDATATYPE), &g_DontSave); if (Pos == 0xffffffff) { __leave; }
DataTypeList = ((PDATATYPE *) DataTypes.Buf)[Pos];
//
// Get the data objects
//
DataObjectCount = 0;
Dll = (PDGDLL) g_DllList.Buf; Dll += (UINT) DataTypeList->Reserved;
g_CurrentDll = Dll;
//
// Gather Info UI
//
if (Dll->GatherInfoUI) { if (!Dll->GatherInfoUI (Dll->Library, DataTypeList->DataTypeId)) { __leave; } }
if (!(DataTypeList->Flags & (DTF_NO_DATA_OBJECT))) {
TurnOnWaitCursor(); DataObjectList = Dll->GiveDataObjectList (DataTypeList->DataTypeId, &DataObjectCount); TurnOffWaitCursor();
if (!DataObjectList || !DataObjectCount) { MessageBox (NULL, "There are no items of this type to choose from.", NULL, MB_OK); StartOverFlag = TRUE; __leave; }
//
// User selects them here
//
if (!pSelectDataObjects (DataObjectList, DataObjectCount, DataTypeList, &StartOverFlag)) { __leave; } }
//
// Display Optional UI
//
Args.Version = UPGWIZ_VERSION; Args.InboundInfDir = g_SrcInfPath; Args.OutboundDir = g_DestPath; Args.DataTypeId = DataTypeList->DataTypeId; Args.StartOverFlag = &StartOverFlag;
if (Dll->DisplayOptionalUI) { if (!Dll->DisplayOptionalUI (&Args)) { __leave; } }
//
// Optional text
//
if (DataTypeList->Flags & (DTF_REQUEST_TEXT|DTF_REQUEST_DESCRIPTION)) {
SelectedDataObject = NULL; for (u = 0 ; u < DataObjectCount ; u++) { if (DataObjectList[u].Flags & DOF_SELECTED) { if (SelectedDataObject) { SelectedDataObject = NULL; break; }
SelectedDataObject = &DataObjectList[u]; } }
Args.OptionalText = MemAlloc (g_hHeap, 0, DataTypeList->MaxTextSize + 1); Args.OptionalDescription = MemAlloc (g_hHeap, 0, 81);
if (!pGetOptionalText ( DataTypeList->OptionalTextTitle, DataTypeList->OptionalDescTitle, &Args.OptionalDescription, &Args.OptionalText, DataTypeList->MaxTextSize, DataTypeList, SelectedDataObject, &StartOverFlag )) { __leave; }
if (*Args.OptionalText == 0) { MemFree (g_hHeap, 0, Args.OptionalText); Args.OptionalText = NULL; }
if (*Args.OptionalDescription == 0) { MemFree (g_hHeap, 0, Args.OptionalDescription); Args.OptionalDescription = NULL; } }
//
// Generate the output
//
Args.Version = UPGWIZ_VERSION; Args.InboundInfDir = g_SrcInfPath; Args.OutboundDir = g_DestPath; Args.DataTypeId = DataTypeList->DataTypeId;
if (!g_DontSave) {
TurnOnWaitCursor(); if (Dll->GenerateOutput (&Args)) { Saved = TRUE; TurnOffWaitCursor(); } else { TurnOffWaitCursor(); MessageBox (NULL, "An error occurred while trying to save the report information.", "Report Not Saved", MB_OK); Saved = FALSE; } } else { Saved = TRUE; }
if (Saved) { pThankYouBox (&StartOverFlag); }
if (Args.OptionalText) { MemFree (g_hHeap, 0, Args.OptionalText); }
if (Args.OptionalDescription) { MemFree (g_hHeap, 0, Args.OptionalDescription); }
g_CurrentDll = NULL; } __finally {
//
// Done
//
pFreeDllList (&g_DllList, g_DllListData); FreeGrowBuffer (&DataTypes); }
return StartOverFlag; }
BOOL CALLBACK pDataTypeProc ( HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { static PSELECTDATAARGS Args; PDATATYPE DataType; UINT u; HWND List; UINT Index;
switch (uMsg) { case WM_INITDIALOG: pSetDefGUIFont(hdlg);
Args = (PSELECTDATAARGS) lParam;
List = GetDlgItem (hdlg, IDC_DT_LIST);
for (u = 0 ; u < Args->PtrCount ; u++) { DataType = Args->DataTypePtrs[u];
Index = SendMessage (List, LB_ADDSTRING, 0, (LPARAM) DataType->Name); SendMessage (List, LB_SETITEMDATA, Index, u); }
CheckDlgButton (hdlg, IDC_DONT_SAVE, Args->NoSave ? BST_CHECKED : BST_UNCHECKED);
EnableWindow (GetDlgItem (hdlg, IDOK), FALSE); return FALSE;
case WM_COMMAND: switch (LOWORD (wParam)) {
case IDC_DT_LIST:
if (HIWORD (wParam) == LBN_SELCHANGE) {
EnableWindow (GetDlgItem (hdlg, IDOK), TRUE);
List = GetDlgItem (hdlg, IDC_DT_LIST); Index = SendMessage (List, LB_GETCURSEL, 0, 0); u = SendMessage (List, LB_GETITEMDATA, Index, 0);
DataType = Args->DataTypePtrs[u];
SetDlgItemText (hdlg, IDC_DESCRIPTION, DataType->Description);
} else if (HIWORD (wParam) == LBN_DBLCLK) {
PostMessage (hdlg, WM_COMMAND, MAKELPARAM(IDOK,BN_CLICKED), 0);
}
break;
case IDOK: List = GetDlgItem (hdlg, IDC_DT_LIST); Index = SendMessage (List, LB_GETCURSEL, 0, 0); Args->Selection = SendMessage (List, LB_GETITEMDATA, Index, 0);
Args->NoSave = IsDlgButtonChecked (hdlg, IDC_DONT_SAVE);
EndDialog (hdlg, LOWORD (wParam)); break;
case IDCANCEL: EndDialog (hdlg, LOWORD (wParam)); break;
}
break; }
return FALSE; }
UINT pSelectDataType ( IN PDATATYPE *DataTypePtrs, IN UINT PtrCount, IN OUT PBOOL DontSave ) { SELECTDATAARGS Args;
Args.Selection = 0xffffffff; Args.DataTypePtrs = DataTypePtrs; Args.PtrCount = PtrCount; Args.NoSave = *DontSave;
DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_DATA_TYPE), NULL, pDataTypeProc, (LPARAM) &Args);
*DontSave = Args.NoSave;
return Args.Selection; }
VOID pToggleSelection ( HWND TreeView, HTREEITEM TreeItem, BOOL OneSelection ) { static HTREEITEM LastSet; UINT State; PDATAOBJECT DataObject; TVITEM Item;
Item.mask = TVIF_HANDLE|TVIF_STATE|TVIF_PARAM; Item.hItem = TreeItem; Item.stateMask = TVIS_STATEIMAGEMASK;
TreeView_GetItem (TreeView, &Item);
State = Item.state & TVIS_STATEIMAGEMASK; DataObject = (PDATAOBJECT) Item.lParam;
if (State) { if (((State >> 12) & 0x03) == 2) { State = INDEXTOSTATEIMAGEMASK(1); g_Selections--; DataObject->Flags &= ~DOF_SELECTED; } else { if (OneSelection && g_Selections == 1) { pToggleSelection (TreeView, LastSet, FALSE); }
State = INDEXTOSTATEIMAGEMASK(2); g_Selections++; DataObject->Flags |= DOF_SELECTED;
LastSet = TreeItem; }
Item.mask = TVIF_HANDLE|TVIF_STATE; Item.hItem = TreeItem; Item.state = State; Item.stateMask = TVIS_STATEIMAGEMASK;
TreeView_SetItem (TreeView, &Item); InvalidateRect (TreeView, NULL, TRUE); } }
HTREEITEM TreeView_FindItem ( IN HWND TreeView, IN PCSTR String, IN HTREEITEM Parent OPTIONAL ) { HTREEITEM Child; TVITEM Item; CHAR Buffer[1024];
if (!Parent) { Child = TreeView_GetRoot (TreeView); } else { Child = TreeView_GetChild (TreeView, Parent); }
while (Child) {
Item.mask = TVIF_TEXT|TVIF_HANDLE; Item.hItem = Child; Item.pszText = Buffer; Item.cchTextMax = 1024;
TreeView_GetItem (TreeView, &Item);
if (StringIMatch (String, Buffer)) { break; }
Child = TreeView_GetNextSibling (TreeView, Child); }
return Child; }
VOID pAddSubStringToTreeControl ( IN HWND TreeView, IN PSTR Path, IN BOOL Checked, IN HTREEITEM Parent, OPTIONAL IN LPARAM lParam ) { TVINSERTSTRUCT is; PSTR p; HTREEITEM Child; BOOL CheckThis = FALSE; BOOL HasBitmap = FALSE; HTREEITEM ExistingItem; PDATAOBJECT d = (PDATAOBJECT) lParam;
p = _mbschr (Path, '\\'); if (p && !(d->Flags & DOF_NO_SPLIT_ON_WACK)) { *p = 0; } else { CheckThis = Checked; HasBitmap = TRUE; }
RestoreWacks (Path);
is.hParent = Parent; is.hInsertAfter = d->Flags & DOF_NO_SORT ? TVI_LAST : TVI_SORT;
ExistingItem = TreeView_FindItem (TreeView, Path, Parent);
is.item.mask = 0; if (!ExistingItem) { is.item.mask = TVIF_TEXT; is.item.pszText = Path; } else { is.item.mask = TVIF_HANDLE; is.item.hItem = ExistingItem; }
if (HasBitmap) { is.item.mask |= TVIF_STATE|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM; is.item.iImage = 0; is.item.iSelectedImage = 1; is.item.state = CheckThis ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1); is.item.stateMask = TVIS_STATEIMAGEMASK; is.item.lParam = lParam;
if (CheckThis) { g_Selections++; } }
if (ExistingItem) { if (is.item.mask) { TreeView_SetItem (TreeView, &is.item); }
Child = ExistingItem; } else { Child = TreeView_InsertItem (TreeView, &is); }
if (p && !(d->Flags & DOF_NO_SPLIT_ON_WACK)) { pAddSubStringToTreeControl (TreeView, p + 1, Checked, Child, lParam); } }
VOID pAddStringToTreeControl ( IN HWND TreeView, IN PCSTR Path, IN BOOL Checked, IN LPARAM lParam ) { PSTR PathCopy;
PathCopy = DuplicateText (Path);
pAddSubStringToTreeControl (TreeView, PathCopy, Checked, NULL, lParam);
FreeText (PathCopy); }
BOOL CALLBACK pDataObjectProc ( HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { static PSELECTOBJECTSARGS Args; static HIMAGELIST ImageList; static BOOL OneSelection; UINT u; HWND TreeView; LPNMHDR pnmh; TVHITTESTINFO HitTest; HTREEITEM TreeItem; LPNMTVKEYDOWN KeyDown; TVITEM Item; PDATAOBJECT DataObject; POINT pt;
switch (uMsg) { case WM_INITDIALOG: pSetDefGUIFont(hdlg);
Args = (PSELECTOBJECTSARGS) lParam; OneSelection = Args->SelectOneOnly;
if (OneSelection) { SetDlgItemText (hdlg, IDC_DESCRIPTION, "&Select the Item to Report:"); }
SetWindowText (hdlg, Args->Name);
g_Selections = 0;
TreeView = GetDlgItem (hdlg, IDC_OBJECTS);
ImageList = ImageList_LoadImage ( g_hInst, MAKEINTRESOURCE(IDB_TREE_IMAGES), 16, 0, CLR_DEFAULT, IMAGE_BITMAP, LR_LOADTRANSPARENT );
TreeView_SetImageList (TreeView, ImageList, TVSIL_STATE);
for (u = 0 ; u < Args->ArraySize ; u++) { pAddStringToTreeControl ( TreeView, Args->DataObjectArray[u].NameOrPath, OneSelection ? FALSE : (Args->DataObjectArray[u].Flags & DOF_SELECTED) ? TRUE : FALSE, (LPARAM) (&Args->DataObjectArray[u]) ); }
InvalidateRect (TreeView, NULL, TRUE); EnableWindow (GetDlgItem (hdlg, IDOK), g_Selections != 0); return FALSE;
case WM_COMMAND: switch (LOWORD (wParam)) {
case IDC_START_OVER: *Args->StartOverFlag = TRUE; EndDialog (hdlg, LOWORD (wParam)); break;
case IDOK: EndDialog (hdlg, LOWORD (wParam)); break;
case IDCANCEL: EndDialog (hdlg, LOWORD (wParam)); break;
}
break;
case WM_NOTIFY: pnmh = (LPNMHDR) lParam;
if (pnmh->code == NM_CLICK) { GetCursorPos (&HitTest.pt); ScreenToClient (pnmh->hwndFrom, &HitTest.pt);
TreeView_HitTest (pnmh->hwndFrom, &HitTest);
if (HitTest.flags & TVHT_ONITEMSTATEICON) {
pToggleSelection (pnmh->hwndFrom, HitTest.hItem, OneSelection); EnableWindow (GetDlgItem (hdlg, IDOK), g_Selections != 0); } }
else if (pnmh->code == NM_RCLICK) { GetCursorPos (&HitTest.pt); pt.x = HitTest.pt.x; pt.y = HitTest.pt.y; ScreenToClient (pnmh->hwndFrom, &HitTest.pt);
TreeView_HitTest (pnmh->hwndFrom, &HitTest);
Item.mask = TVIF_HANDLE|TVIF_PARAM; Item.hItem = HitTest.hItem;
TreeView_GetItem (pnmh->hwndFrom, &Item);
TreeView_SelectItem (pnmh->hwndFrom, HitTest.hItem);
DataObject = (PDATAOBJECT) Item.lParam;
if (g_CurrentDll->Handle_RMouse) { if (g_CurrentDll->Handle_RMouse (g_CurrentDll->Library, pnmh->hwndFrom, DataObject, &pt)) {
Item.pszText = (PSTR)DataObject->NameOrPath; Item.cchTextMax = strlen (DataObject->NameOrPath); Item.mask = TVIF_HANDLE|TVIF_TEXT; TreeView_SetItem (pnmh->hwndFrom, &Item); InvalidateRect (pnmh->hwndFrom, NULL, TRUE); } } }
//
// The tree control beeps with keyboard input; we have no way
// to eat the messages. This codes is disabled.
//
else if (pnmh->code == TVN_KEYDOWN && pnmh->code == 0) {
KeyDown = (LPNMTVKEYDOWN) pnmh;
if (KeyDown->wVKey == VK_SPACE) {
TreeItem = TreeView_GetSelection (pnmh->hwndFrom);
if (TreeItem) { pToggleSelection (pnmh->hwndFrom, TreeItem, OneSelection); EnableWindow (GetDlgItem (hdlg, IDOK), g_Selections != 0); } } }
break;
case WM_DESTROY: ImageList_Destroy (ImageList); break;
}
return FALSE; }
BOOL pSelectDataObjects ( IN OUT PDATAOBJECT DataObjectArray, IN UINT ArraySize, IN PDATATYPE DataType, OUT PBOOL StartOverFlag ) { SELECTOBJECTSARGS Args;
Args.DataObjectArray = DataObjectArray; Args.ArraySize = ArraySize; Args.Name = DataType->Name; Args.SelectOneOnly = (DataType->Flags & DTF_ONE_SELECTION) != 0; Args.StartOverFlag = StartOverFlag;
return IDOK == DialogBoxParam ( g_hInst, MAKEINTRESOURCE(IDD_DATA_OBJECTS), NULL, pDataObjectProc, (LPARAM) &Args ); }
BOOL CALLBACK pSupplyTextProc ( HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { static PSUPPLYTEXTARGS Args; BOOL b; CHAR name[MEMDB_MAX];
switch (uMsg) { case WM_INITDIALOG: pSetDefGUIFont(hdlg);
Args = (PSUPPLYTEXTARGS) lParam;
if (Args->TextTitle) { SetDlgItemText (hdlg, IDC_TEXT_TITLE, Args->TextTitle); }
if (Args->DescTitle) { SetDlgItemText (hdlg, IDC_DESC_TITLE, Args->DescTitle); }
SetDlgItemText (hdlg, IDC_DATA_TYPE, Args->DataTypeName); if (Args->DataObjectName) {
StringCopy (name, Args->DataObjectName); RestoreWacks(name);
SetDlgItemText (hdlg, IDC_SELECTION, name); }
SendMessage (GetDlgItem (hdlg, IDC_DESCRIPTION), EM_LIMITTEXT, 80, 0); SendMessage (GetDlgItem (hdlg, IDC_TEXT_MSG), EM_LIMITTEXT, Args->MaxSize, 0);
if (Args->NoText) {
SetDlgItemText (hdlg, IDC_TEXT_MSG, "(not applicable)"); EnableWindow (GetDlgItem (hdlg, IDC_TEXT_MSG), FALSE);
} else if (Args->NoDesc) {
SetDlgItemText (hdlg, IDC_DESCRIPTION, "(not applicable)"); EnableWindow (GetDlgItem (hdlg, IDC_DESCRIPTION), FALSE); }
if (Args->ReqDesc || Args->ReqText) { EnableWindow (GetDlgItem (hdlg, IDOK), FALSE); }
return FALSE;
case WM_COMMAND: switch (LOWORD (wParam)) {
case IDC_DESCRIPTION: case IDC_TEXT_MSG: if (HIWORD (wParam) == EN_CHANGE) { b = !Args->ReqDesc || GetWindowTextLength (GetDlgItem (hdlg, IDC_DESCRIPTION)) != 0; b &= !Args->ReqText || GetWindowTextLength (GetDlgItem (hdlg, IDC_TEXT_MSG)) != 0;
EnableWindow (GetDlgItem (hdlg, IDOK), b); } break;
case IDC_START_OVER: *Args->StartOverFlag = TRUE; EndDialog (hdlg, LOWORD (wParam)); break;
case IDOK: if (Args->NoDesc) { *((PSTR) (*Args->NewDesc)) = 0; } else { GetDlgItemText (hdlg, IDC_DESCRIPTION, (PSTR) (*Args->NewDesc), 81); }
if (Args->NoText) { *((PSTR) (*Args->NewText)) = 0; } else { GetDlgItemText (hdlg, IDC_TEXT_MSG, (PSTR) (*Args->NewText), Args->MaxSize + 1); }
EndDialog (hdlg, LOWORD (wParam)); break;
case IDCANCEL: EndDialog (hdlg, LOWORD (wParam)); break;
}
break; }
return FALSE; }
BOOL pGetOptionalText ( IN PCSTR TextTitle, OPTIONAL IN PCSTR DescTitle, IN PCSTR *NewDesc, IN PCSTR *NewText, IN UINT MaxSize, IN PDATATYPE DataType, IN PDATAOBJECT DataObject, OPTIONAL OUT PBOOL StartOverFlag ) { SUPPLYTEXTARGS Args; BOOL b = FALSE;
Args.TextTitle = TextTitle; Args.DescTitle = DescTitle; Args.NewText = NewText; Args.NewDesc = NewDesc; Args.MaxSize = MaxSize; Args.DataTypeName = DataType->Name;
if (DataObject) { Args.DataObjectName = DataObject->NameOrPath; } else { Args.DataObjectName = NULL; }
Args.NoDesc = ((DataType->Flags & DTF_REQUEST_DESCRIPTION) == 0); Args.NoText = ((DataType->Flags & DTF_REQUEST_TEXT) == 0); Args.ReqDesc = ((DataType->Flags & DTF_REQUIRE_TEXT) == DTF_REQUIRE_TEXT); Args.ReqText = ((DataType->Flags & DTF_REQUIRE_DESCRIPTION) == DTF_REQUIRE_DESCRIPTION); Args.StartOverFlag = StartOverFlag;
if (IDOK == DialogBoxParam ( g_hInst, MAKEINTRESOURCE(IDD_SUPPLY_TEXT), NULL, pSupplyTextProc, (LPARAM) &Args )) { b = TRUE; }
return b; }
BOOL CALLBACK pThankYouProc ( HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch (uMsg) {
case WM_COMMAND: switch (LOWORD (wParam)) {
case IDC_START_OVER: EndDialog (hdlg, LOWORD (wParam)); break;
case IDCANCEL: EndDialog (hdlg, LOWORD (wParam)); break;
}
break; }
return FALSE; }
VOID pThankYouBox ( IN PBOOL StartOverFlag ) { if (IDC_START_OVER == DialogBox (g_hInst, MAKEINTRESOURCE(IDD_DONE), NULL, pThankYouProc)) { *StartOverFlag = TRUE; } }
|