/*++ Copyright (c) 1996 Microsoft Corporation Module Name: util.c Abstract: This file implements utility functions. Environment: WIN32 User Mode Author: Wesley Witt (wesw) 17-Feb-1996 --*/ #include "wizard.h" #pragma hdrstop PLATFORM_INFO Platforms[] = { { TEXT("Windows NT x86"), TEXT("i386"), 0, FAX_INSTALLED_PLATFORM_X86, NULL, FALSE }, { TEXT("Windows NT Alpha_AXP"), TEXT("alpha"), 0, FAX_INSTALLED_PLATFORM_ALPHA, NULL, FALSE }, }; DWORD CountPlatforms = (sizeof(Platforms)/sizeof(PLATFORM_INFO)); // Sequentially enumerate platforms WORD EnumPlatforms[4]; typedef struct _STRING_TABLE { DWORD ResourceId; BOOL UseTitle; LPTSTR String; } STRING_TABLE, *PSTRING_TABLE; static STRING_TABLE StringTable[] = { { IDS_TITLE_WKS, FALSE, NULL }, { IDS_TITLE_SRV, FALSE, NULL }, { IDS_TITLE_PP, FALSE, NULL }, { IDS_TITLE_RA, FALSE, NULL }, { IDS_COPYING, FALSE, NULL }, { IDS_COPY_WAITMSG, TRUE, NULL }, { IDS_COULD_NOT_DELETE_FAX_PRINTER, FALSE, NULL }, { IDS_COULD_NOT_DELETE_FILES, FALSE, NULL }, { IDS_CREATING_FAXPRT, FALSE, NULL }, { IDS_CREATING_GROUPS, FALSE, NULL }, { IDS_DEFAULT_PRINTER, FALSE, NULL }, { IDS_DEFAULT_SHARE, FALSE, NULL }, { IDS_DELETE_WAITMSG, TRUE, NULL }, { IDS_DELETING, FALSE, NULL }, { IDS_DELETING_FAX_PRINTERS, FALSE, NULL }, { IDS_DELETING_FAX_SERVICE, FALSE, NULL }, { IDS_DELETING_GROUPS, FALSE, NULL }, { IDS_DELETING_REGISTRY, FALSE, NULL }, { IDS_DEVICEINIT_LABEL01, TRUE, NULL }, { IDS_ERR_TITLE, TRUE, NULL }, { IDS_FAXCLIENT_SETUP, FALSE, NULL }, { IDS_FAX_PRINTER_PENDING_DELETION, FALSE, NULL }, { IDS_FAX_SHARE_COMMENT, FALSE, NULL }, { IDS_INBOUND_DIR, FALSE, NULL }, { IDS_INIT_TAPI, FALSE, NULL }, { IDS_INSTALLING_FAXSVC, FALSE, NULL }, { IDS_INVALID_DIRECTORY, FALSE, NULL }, { IDS_INVALID_LOCAL_PRINTER_NAME, FALSE, NULL }, { IDS_LABEL01_LAST, TRUE, NULL }, { IDS_LABEL02_LAST, TRUE, NULL }, { IDS_LABEL_PRINTERNAME, FALSE, NULL }, { IDS_LASTUNINSTALL_LABEL01, TRUE, NULL }, { IDS_NO_MODEM, FALSE, NULL }, { IDS_QUERY_CANCEL, FALSE, NULL }, { IDS_QUERY_UNINSTALL, TRUE, NULL }, { IDS_SETTING_REGISTRY, FALSE, NULL }, { IDS_SHARE_FAX_PRINTER, FALSE, NULL }, { IDS_STARTING_FAXSVC, FALSE, NULL }, { IDS_TITLE, TRUE, NULL }, { IDS_WELCOME_LABEL01, TRUE, NULL }, { IDS_WELCOME_LABEL02, TRUE, NULL }, { IDS_WRN_SPOOLER, FALSE, NULL }, { IDS_WRN_TITLE, TRUE, NULL }, { IDS_PRINTER_NAME, FALSE, NULL }, { IDS_CSID, FALSE, NULL }, { IDS_TSID, FALSE, NULL }, { IDS_DEST_DIR, FALSE, NULL }, { IDS_PROFILE, FALSE, NULL }, { IDS_ACCOUNTNAME, FALSE, NULL }, { IDS_PASSWORD, FALSE, NULL }, { IDS_NO_TAPI_DEVICES, FALSE, NULL }, { IDS_USER_MUST_BE_ADMIN, TRUE, NULL }, { IDS_COULD_NOT_INSTALL_FAX_SERVICE, FALSE, NULL }, { IDS_COULD_NOT_START_FAX_SERVICE, FALSE, NULL }, { IDS_COULD_NOT_CREATE_PRINTER, FALSE, NULL }, { IDS_PERMISSION_CREATE_PRINTER, FALSE, NULL }, { IDS_COULD_SET_REG_DATA, FALSE, NULL }, { IDS_INVALID_USER, FALSE, NULL }, { IDS_INVALID_USER_NAME, FALSE, NULL }, { IDS_INVALID_AREA_CODE, FALSE, NULL }, { IDS_INVALID_PHONE_NUMBER, FALSE, NULL }, { IDS_ROUTING_REQUIRED, FALSE, NULL }, { IDS_COULD_NOT_COPY_FILES, FALSE, NULL }, { IDS_CANT_USE_FAX_PRINTER, FALSE, NULL }, { IDS_CANT_SET_SERVICE_ACCOUNT, FALSE, NULL }, { IDS_EXCHANGE_IS_RUNNING, FALSE, NULL }, { IDS_DEFAULT_PRINTER_NAME, FALSE, NULL }, { IDS_INSTALLING_EXCHANGE, FALSE, NULL }, { IDS_351_MODEM, FALSE, NULL }, { IDS_LARGEFONTNAME, FALSE, NULL }, { IDS_LARGEFONTSIZE, FALSE, NULL }, { IDS_NO_CLASS1, TRUE, NULL }, { IDS_UAA_MODE, FALSE, NULL }, { IDS_UAA_PRINTER_NAME, FALSE, NULL }, { IDS_UAA_FAX_PHONE, FALSE, NULL }, { IDS_UAA_DEST_PROFILENAME, FALSE, NULL }, { IDS_UAA_ROUTE_PROFILENAME, FALSE, NULL }, { IDS_UAA_PLATFORM_LIST, FALSE, NULL }, { IDS_UAA_DEST_PRINTERLIST, FALSE, NULL }, { IDS_UAA_ACCOUNT_NAME, FALSE, NULL }, { IDS_UAA_PASSWORD, FALSE, NULL }, { IDS_UAA_DEST_DIRPATH, FALSE, NULL }, { IDS_UAA_SERVER_NAME, FALSE, NULL }, { IDS_UAA_SENDER_NAME, FALSE, NULL }, { IDS_UAA_SENDER_FAX_AREA_CODE, FALSE, NULL }, { IDS_UAA_SENDER_FAX_NUMBER, FALSE, NULL } }; #define CountStringTable (sizeof(StringTable)/sizeof(STRING_TABLE)) VOID SetTitlesInStringTable( VOID ) { DWORD i; TCHAR Buffer[1024]; DWORD Index = 0; for (i=0; i0; i--) { if (Path[i] == TEXT('\\')) { Path[i+1] = 0; break; } } return Path; } DWORD ExtraChars( HWND hwnd, LPTSTR TextBuffer ) { RECT Rect; SIZE Size; HDC hdc; DWORD len; HFONT hFont; INT Fit; hdc = GetDC( hwnd ); GetWindowRect( hwnd, &Rect ); hFont = (HFONT)SendMessage( hwnd, WM_GETFONT, 0, 0 ); if (hFont != NULL) { SelectObject( hdc, hFont ); } len = _tcslen( TextBuffer ); if (!GetTextExtentExPoint( hdc, TextBuffer, len, Rect.right - Rect.left, &Fit, NULL, &Size )) { // // can't determine the text extents so we return zero // Fit = len; } ReleaseDC( hwnd, hdc ); if (Fit < (INT)len) { return len - Fit; } return 0; } LPTSTR CompactFileName( LPCTSTR FileNameIn, DWORD CharsToRemove ) { LPTSTR start; LPTSTR FileName; DWORD FileNameLen; LPTSTR lastPart; DWORD lastPartLen; DWORD lastPartPos; LPTSTR midPart; DWORD midPartPos; if (! FileNameIn) { return NULL; } FileName = MemAlloc( (_tcslen( FileNameIn ) + 16) * sizeof(TCHAR) ); if (! FileName) { return NULL; } _tcscpy( FileName, FileNameIn ); FileNameLen = _tcslen(FileName); if (FileNameLen < CharsToRemove + 3) { // nothing to remove return FileName; } lastPart = _tcsrchr(FileName, TEXT('\\') ); if (! lastPart) { // nothing to remove return FileName; } lastPartLen = _tcslen(lastPart); // temporary null-terminate FileName lastPartPos = lastPart - FileName; FileName[lastPartPos] = TEXT('\0'); midPart = _tcsrchr(FileName, TEXT('\\') ); // restore FileName[lastPartPos] = TEXT('\\'); if (!midPart) { // nothing to remove return FileName; } midPartPos = midPart - FileName; if ( ((DWORD) (lastPart - midPart) ) >= (CharsToRemove + 3) ) { // found start = midPart+1; start[0] = start[1] = start[2] = TEXT('.'); start += 3; _tcscpy(start, lastPart); start[lastPartLen] = TEXT('\0'); return FileName; } do { FileName[midPartPos] = TEXT('\0'); midPart = _tcsrchr(FileName, TEXT('\\') ); // restore FileName[midPartPos] = TEXT('\\'); if (!midPart) { // nothing to remove return FileName; } midPartPos = midPart - FileName; if ( (DWORD) ((lastPart - midPart) ) >= (CharsToRemove + 3) ) { // found start = midPart+1; start[0] = start[1] = start[2] = TEXT('.'); start += 3; _tcscpy(start, lastPart); start[lastPartLen] = TEXT('\0'); return FileName; } } while ( 1 ); } VOID DoExchangeInstall( HWND hwnd ) { // // always update the mapi service inf // so that the user can add the fax // service to their profile even if they // choose not to do so now. // AddFaxAbToMapiSvcInf(); AddFaxXpToMapiSvcInf(); InstallExchangeClientExtension( EXCHANGE_CLIENT_EXT_NAME, EXCHANGE_CLIENT_EXT_FILE, EXCHANGE_CONTEXT_MASK ); if ((InstallMode & INSTALL_NEW) && WizData.UseExchange) { if (!MapiAvail) { // // the user wants to use exchange, but it has not // been installed yet. so lets install it! // WCHAR InstallCommand[256]; STARTUPINFO si; PROCESS_INFORMATION pi; GetExchangeInstallCommand( InstallCommand ); GetStartupInfo( &si ); if (CreateProcessW( NULL, InstallCommand, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi )) { // // wait for the exchange install to finish // WaitForSingleObject( pi.hProcess, INFINITE ); InitializeMapi(); // // create a profile and add the fax address book // CreateDefaultMapiProfile( WizData.MapiProfile ); InstallFaxAddressBook( hwnd, WizData.MapiProfile ); InstallFaxTransport( WizData.MapiProfile ); } } else { CreateDefaultMapiProfile( WizData.MapiProfile ); if (!IsMapiServiceInstalled( WizData.MapiProfile, FAXAB_SERVICE_NAME )) { InstallFaxAddressBook( hwnd, WizData.MapiProfile ); } if (!IsMapiServiceInstalled( WizData.MapiProfile, FAXXP_SERVICE_NAME )) { InstallFaxTransport( WizData.MapiProfile ); } } // // check to see if exchange is running, // if is is then give the user a warning to restart it // if (IsExchangeRunning()) { PopUpMsg( hwnd, IDS_EXCHANGE_IS_RUNNING, FALSE, 0 ); } } } BOOL CreateNetworkShare( LPTSTR Path, LPTSTR ShareName, LPTSTR Comment ) { SHARE_INFO_2 ShareInfo; NET_API_STATUS rVal; TCHAR ExpandedPath[MAX_PATH*2]; ExpandEnvironmentStrings( Path, ExpandedPath, sizeof(ExpandedPath) ); ShareInfo.shi2_netname = ShareName; ShareInfo.shi2_type = STYPE_DISKTREE; ShareInfo.shi2_remark = Comment; ShareInfo.shi2_permissions = ACCESS_ALL; ShareInfo.shi2_max_uses = (DWORD) -1, ShareInfo.shi2_current_uses = (DWORD) -1; ShareInfo.shi2_path = ExpandedPath; ShareInfo.shi2_passwd = NULL; rVal = NetShareAdd( NULL, 2, (LPBYTE) &ShareInfo, NULL ); return rVal == 0; } BOOL DeleteNetworkShare( LPTSTR ShareName ) { NET_API_STATUS rVal; rVal = NetShareDel( NULL, ShareName, 0 ); return rVal == 0; } BOOL DeleteDirectoryTree( LPWSTR Root ) { WCHAR FileName[MAX_PATH*2]; WIN32_FIND_DATA FindData; HANDLE hFind; swprintf( FileName, L"%s\\*", Root ); hFind = FindFirstFile( FileName, &FindData ); if (hFind == INVALID_HANDLE_VALUE) { return FALSE; } do { if (FindData.cFileName[0] == L'.') { continue; } if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { DeleteDirectoryTree( FindData.cFileName ); } else { MyDeleteFile( FindData.cFileName ); } } while (FindNextFile( hFind, &FindData )); FindClose( hFind ); RemoveDirectory( Root ); return TRUE; } BOOL MyDeleteFile( LPWSTR FileName ) { if (GetFileAttributes( FileName ) == 0xffffffff) { // // the file does not exists // return TRUE; } if (!DeleteFile( FileName )) { if (MoveFileEx( FileName, NULL, MOVEFILE_DELAY_UNTIL_REBOOT )) { RebootRequired = TRUE; return TRUE; } else { return FALSE; } } else { return TRUE; } } // // RafaelL: 4/3/97 // this is a work-around for Setupapi!SetupSetPlatformPathOverride bug. // but this also can be useful for custom cross-platform layout. // BOOL PlatformOverride( LPTSTR ThisPlatformName, // "i386" LPTSTR Override, // "alpha" LPTSTR SourceRoot, // "foo\...\bar\i386\" LPTSTR Result // "foo\...\bar\alpha\" ) { DWORD Len; DWORD Pos; LPTSTR LastPart; LPTSTR PlatformPart; BOOL IsBackSlashAtEnd = 0; if ( (!ThisPlatformName) || (!Override) || (!SourceRoot) || (!Result) ) { // don't do anything: don't break anybody. return TRUE; } _tcscpy( Result, SourceRoot ); Len = _tcslen(Result); LastPart = _tcsrchr(Result, TEXT('\\') ); if (!LastPart) { return FALSE; } Pos = LastPart - Result; if ( Pos == (Len - 1) ) { IsBackSlashAtEnd = 1; *LastPart = TEXT('\0'); PlatformPart = _tcsrchr(Result, TEXT('\\') ); if (!PlatformPart) { return FALSE; } } else { PlatformPart = LastPart; } PlatformPart++; if ( _tcsicmp( PlatformPart, ThisPlatformName) != 0 ) { return FALSE; } _tcscpy (PlatformPart, Override); Len = _tcslen(Result); if (IsBackSlashAtEnd) { Result[Len] = TEXT ('\\'); Result[Len+1] = TEXT ('\0'); } else { Result[Len] = TEXT ('\0'); } return TRUE; }