windows-nt/Source/XPSP1/NT/printscan/fax/setup/wizdll/util.c
2020-09-26 16:20:57 +08:00

795 lines
19 KiB
C

/*++
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; i<CountStringTable; i++) {
if (StringTable[i].UseTitle) {
if (LoadString(
FaxWizModuleHandle,
StringTable[i].ResourceId,
Buffer,
sizeof(Buffer)
))
{
if (StringTable[i].String) {
MemFree( StringTable[i].String );
}
StringTable[i].String = (LPTSTR) MemAlloc( StringSize( Buffer ) + 256 );
if (StringTable[i].String) {
switch (RequestedSetupType) {
case SETUP_TYPE_SERVER:
Index = 1;
break;
case SETUP_TYPE_WORKSTATION:
Index = 0;
break;
case SETUP_TYPE_CLIENT:
Index = 2;
break;
case SETUP_TYPE_POINT_PRINT:
Index = 2;
break;
case SETUP_TYPE_REMOTE_ADMIN:
Index = 3;
break;
}
_stprintf( StringTable[i].String, Buffer, StringTable[Index].String );
}
}
}
}
}
VOID
InitializeStringTable(
VOID
)
{
DWORD i;
TCHAR Buffer[512];
SYSTEM_INFO SystemInfo;
GetSystemInfo( &SystemInfo );
switch (SystemInfo.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_INTEL:
_stprintf(ThisPlatformName, TEXT("i386") );
break;
case PROCESSOR_ARCHITECTURE_ALPHA:
_stprintf(ThisPlatformName, TEXT("alpha") );
break;
case PROCESSOR_ARCHITECTURE_MIPS:
_stprintf(ThisPlatformName, TEXT("mips") );
break;
case PROCESSOR_ARCHITECTURE_PPC:
_stprintf(ThisPlatformName, TEXT("ppc") );
break;
default:
DebugPrint(( TEXT("Unsupported platform!") ));
break;
}
for (i=0; i<CountStringTable; i++) {
if (LoadString(
FaxWizModuleHandle,
StringTable[i].ResourceId,
Buffer,
sizeof(Buffer)
)) {
StringTable[i].String = (LPTSTR) MemAlloc( StringSize( Buffer ) + 256 );
if (!StringTable[i].String) {
StringTable[i].String = TEXT("");
} else {
_tcscpy( StringTable[i].String, Buffer );
}
} else {
StringTable[i].String = TEXT("");
}
}
SetTitlesInStringTable();
}
LPTSTR
GetString(
DWORD ResourceId
)
{
DWORD i;
for (i=0; i<CountStringTable; i++) {
if (StringTable[i].ResourceId == ResourceId) {
return StringTable[i].String;
}
}
return NULL;
}
int
PopUpMsg(
HWND hwnd,
DWORD ResourceId,
BOOL Error,
DWORD Type
)
{
return MessageBox(
hwnd,
GetString( ResourceId ),
GetString( Error ? IDS_ERR_TITLE : IDS_WRN_TITLE ),
MB_SETFOREGROUND | (Error ? MB_ICONEXCLAMATION : MB_ICONINFORMATION) | (Type == 0 ? MB_OK : Type)
);
}
int
PopUpMsgFmt(
HWND hwnd,
DWORD ResourceId,
BOOL Error,
DWORD Type,
...
)
{
TCHAR buf[1024];
va_list arg_ptr;
va_start(arg_ptr, Type);
_vsntprintf( buf, sizeof(buf), GetString( ResourceId ), arg_ptr );
return MessageBox(
hwnd,
buf,
GetString( Error ? IDS_ERR_TITLE : IDS_WRN_TITLE ),
MB_SETFOREGROUND | (Error ? MB_ICONEXCLAMATION : MB_ICONINFORMATION) | (Type == 0 ? MB_OK : Type)
);
}
LPTSTR
GetProductName(
VOID
)
{
DWORD Index;
switch (RequestedSetupType) {
case SETUP_TYPE_SERVER:
Index = 1;
break;
case SETUP_TYPE_WORKSTATION:
Index = 0;
break;
case SETUP_TYPE_CLIENT:
Index = 2;
break;
case SETUP_TYPE_POINT_PRINT:
Index = 2;
break;
case SETUP_TYPE_REMOTE_ADMIN:
Index = 3;
break;
}
return StringTable[Index].String;
}
VOID
SetWizPageTitle(
HWND hWnd
)
{
PropSheet_SetTitle( hWnd, 0, GetProductName() );
}
LPTSTR
RemoveLastNode(
LPTSTR Path
)
{
DWORD i;
if (Path == NULL || Path[0] == 0) {
return Path;
}
i = _tcslen(Path)-1;
if (Path[i] == TEXT('\\')) {
Path[i] = 0;
i -= 1;
}
for (; i>0; 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;
}