_Your Own Netscape Plug-in Installer_ by Mark Carolan Listing One char version[REG_STRING], module[REG_STRING], company[REG_STRING], program[REG_STRING], InstallSubdir[REG_STRING], programID[REG_STRING], SearchFile[REG_STRING]; Listing Two LoadString(AppInstance, IDS_MODULE, module, REG_STRING); LoadString(AppInstance, IDS_COMPANY, company, REG_STRING); LoadString(AppInstance, IDS_PROGRAM, program, REG_STRING); LoadString(AppInstance, IDS_VERSION, version, REG_STRING); LoadString(AppInstance, IDS_INSTALLSUBDIR, InstallSubdir, REG_STRING); LoadString(AppInstance, IDS_PROGRAMID, programID, REG_STRING); LoadString(AppInstance, IDS_SEARCHFILE, SearchFile, REG_STRING); Listing Three char *pathsReg[] = { "SOFTWARE", // preset company, // your company program, // your product "Paths" // your private registry info }; char *regEntry[] = { "SOFTWARE", company, program, "Cache" // more private registry info }; Listing Four char *sections[] = { "Software", "Netscape", "Netscape Navigator", "Main", "Install Directory" }; Listing Five char *uninstall[] = { "SOFTWARE", "Microsoft", "Windows", "CurrentVersion", "Uninstall" }; Listing Six hkey = HKEY_CURRENT_USER; samDesired = KEY_ENUMERATE_SUB_KEYS; phkResult = 0; for (int n = 0; n < sectionElements - 1; n++) { res = RegOpenKeyEx( hkey, sections[n], 0, samDesired, &phkResult ); if (phkResult) hkey = phkResult; else break; } res = RegQueryValueEx( hkey, sections[n], NULL, &type, buffer, &bufferSize ); Listing Seven hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)DialogThread, (void*) &ds, 0, &dwThreadId); while (!CONTINUE) Sleep(0); if (!CANCEL_COMMAND) FindFile(&pathList, SearchFile); CANCEL_COMMAND = CONTINUE = FALSE; // reset dbRes = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)IntroDialog, (LPARAM)&pathList); if (CANCEL_COMMAND) return 0; COMPLETE = TRUE; Listing Eight DWORD DialogThread(LPDWORD dw) { DLGSTRUCT *dlg = (DLGSTRUCT*) dw; int dbRes = DialogBox( AppInstance, MAKEINTRESOURCE(dlg->dlgRes), NULL, (DLGPROC)dlg->dlgProc); ExitThread(0); CONTINUE = TRUE; return 0; } Listing Nine void RecurseFileSearch(const char *dirPath, StringList *sl, const char *fileName) { HANDLE h; BOOL searchResult = TRUE; char *bogusFile = "*.*"; char local[MAX_PATH]; WIN32_FIND_DATA findData; DWORD attr; // Did user cancel out in other thread? if (CANCEL_COMMAND) return; strcpy(local, dirPath); if (local[strlen(local) - 1] != '\\') strcat(local, "\\"); strcat(local, bogusFile); searchResult = (BOOL) ((h = FindFirstFile(local, &findData)) != (HANDLE)0xffffffff); while (searchResult) { if (CANCEL_COMMAND) // check again, as some time has elapsed { FindClose(h); return; } local[strlen(local) - strlen(bogusFile)] = 0; strcat(local, findData.cFileName); attr = GetFileAttributes(local); SetDlgItemText(WaitDlg, IDC_WAITINFO, local); if ((attr & FILE_ATTRIBUTE_DIRECTORY) && (*findData.cFileName != '.')) RecurseFileSearch(local, sl, fileName); else if (CompareFile(local, fileName)) { strcpy(local, dirPath); // refresh path info strcat(local, "\\"); if (sl->FindIndex(local) == 0) sl->Insert(local); } strcpy(local, dirPath); // refresh path info if (local[strlen(local) - 1] != '\\') strcat(local, "\\"); strcat(local, bogusFile); searchResult = FindNextFile(h, &findData); } FindClose(h); } Listing Ten BOOL InstallFile(char *szSrcDir, char *szDestDir, char *szSrcFileName) { char szTmpFile[MAX_PATH]; UINT uTmpFileLen; int res; CreateDirectory(szDestDir, NULL); uTmpFileLen = (unsigned)MAX_PATH; // <-size of szTmpFile res = VerInstallFile( 0, szSrcFileName, szSrcFileName, szSrcDir, szDestDir, "", szTmpFile, &uTmpFileLen ); if (res== 0) { DeleteFile(szTmpFile); return TRUE; } else if (res & VIF_SRCOLD) MessageBox(GetFocus(), "The module you are trying to install " "is older than that already installed.", "Bailing out...", MB_OK | MB_ICONHAND); else if (res & VIF_FILEINUSE) MessageBox(GetFocus(), "The old file is still in use. " "Quit Netscape first.", "Bailing out...", MB_OK | MB_ICONHAND); . . . Listing Eleven BOOL CALLBACK IntroDialog( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { static StringList *pl; char pathStr[MAX_PATH]; int nBuffer[512]; int nSelItemsInBuffer, nSelItems, i; MainWin = hwndDlg; switch (uMsg) { case WM_INITDIALOG: pl = (StringList *)lParam; pl->FillListBox(GetDlgItem(hwndDlg, IDC_LIST1)); SetDlgItemText(hwndDlg, IDC_REGISTEREDPATH, PathBuffer); SendMessage(GetDlgItem(hwndDlg, IDC_LIST1), LB_SETSEL, TRUE, (LPARAM) 0); CenterWindow(hwndDlg, GetDesktopWindow()); return TRUE; ... Listing Twelve BOOL MakeKey( HKEY hkey, char *regEntry[], int sectionElements, char *newKey[], int newElements, char *item, char *val) { LPBYTE bytePtr; DWORD createStatus; char *parentKey; int n, res; HKEY phkResult = 0; REGSAM samDesired = KEY_ALL_ACCESS; for (n = 0; n < sectionElements; n++) { res = RegOpenKeyEx( hkey, regEntry[n], 0, samDesired, &phkResult ); if (phkResult) hkey = phkResult; else return FALSE; } if (res != ERROR_SUCCESS) return FALSE; n--; parentKey = regEntry[n]; for (n = 0; n < newElements; n++) { hkey = phkResult; res = RegCreateKeyEx( hkey, newKey[n], 0, parentKey, REG_OPTION_NON_VOLATILE, samDesired, NULL, &phkResult, &createStatus); if (phkResult) { hkey = phkResult; parentKey = newKey[n]; } else return FALSE; } if (res != ERROR_SUCCESS) return FALSE; bytePtr = (unsigned char*) val; res = RegSetValueEx(hkey, item, 0, REG_SZ, bytePtr, strlen(val) + 1); if (res != ERROR_SUCCESS) return FALSE; else return TRUE; } Listing Thirteen // the uninstall command line switch if (strstr(lpszCmdLine, "-u")) REMOVE = TRUE; Listing Fourteen buffPtr = (char*)buffer; // contains retrieved path to "Navigator" directory // conversions are to avoid compile warnings when // moving between signed and unsigned char pointers if (res == ERROR_SUCCESS) AppendDirectory(buffPtr, programID); else *buffer = 0;