mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-31 19:26:42 +00:00
Fix some bugs according to test suite
Delete unused files svn path=/trunk/; revision=22445
This commit is contained in:
@@ -991,7 +991,7 @@ SETUP_CreateDevicesListFromEnumerator(
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
else if (dwRegType != REG_SZ)
|
||||
else if (dwRegType != REG_SZ || dwLength < MAX_GUID_STRING_LEN * sizeof(WCHAR))
|
||||
{
|
||||
rc = ERROR_GEN_FAILURE;
|
||||
goto cleanup;
|
||||
@@ -1077,7 +1077,11 @@ SETUP_CreateDevicesList(
|
||||
KEY_ENUMERATE_SUB_KEYS,
|
||||
&hEnumeratorKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
if (rc == ERROR_FILE_NOT_FOUND)
|
||||
rc = ERROR_INVALID_DATA;
|
||||
goto cleanup;
|
||||
}
|
||||
rc = SETUP_CreateDevicesListFromEnumerator(list, Class, Enumerator, hEnumeratorKey);
|
||||
}
|
||||
else
|
||||
@@ -1155,39 +1159,29 @@ SetupDiGetClassDevsExW(
|
||||
else
|
||||
{
|
||||
hDeviceInfo = SetupDiCreateDeviceInfoListExW(
|
||||
Flags & DIGCF_DEVICEINTERFACE ? NULL : ClassGuid,
|
||||
Flags & (DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES) ? NULL : ClassGuid,
|
||||
NULL, MachineName, NULL);
|
||||
if (hDeviceInfo == INVALID_HANDLE_VALUE)
|
||||
goto cleanup;
|
||||
list = (struct DeviceInfoSet *)hDeviceInfo;
|
||||
}
|
||||
|
||||
if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
|
||||
pClassGuid = NULL;
|
||||
else
|
||||
pClassGuid = &list->ClassGuid;
|
||||
|
||||
if (Flags & DIGCF_PROFILE)
|
||||
FIXME(": flag DIGCF_PROFILE ignored\n");
|
||||
|
||||
/* FIXME: list->ClassGuid is never used! */
|
||||
if (Flags & DIGCF_ALLCLASSES)
|
||||
pClassGuid = NULL;
|
||||
else if (ClassGuid)
|
||||
pClassGuid = ClassGuid;
|
||||
else
|
||||
{
|
||||
rc = SETUP_CreateDevicesList(list, MachineName, pClassGuid, Enumerator);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
ret = hDeviceInfo;
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
goto cleanup;
|
||||
}
|
||||
else if (Flags & DIGCF_DEVICEINTERFACE)
|
||||
{
|
||||
if (ClassGuid == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (Flags & DIGCF_DEVICEINTERFACE)
|
||||
{
|
||||
rc = SETUP_CreateInterfaceList(list, MachineName, ClassGuid, Enumerator, Flags & DIGCF_PRESENT);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
@@ -1198,6 +1192,16 @@ SetupDiGetClassDevsExW(
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Flags & DIGCF_ALLCLASSES)
|
||||
rc = SETUP_CreateDevicesList(list, MachineName, NULL, Enumerator);
|
||||
else if (ClassGuid)
|
||||
rc = SETUP_CreateDevicesList(list, MachineName, pClassGuid, Enumerator);
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rc = SETUP_CreateDevicesList(list, MachineName, ClassGuid, Enumerator);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
* SetupX .inf file parsing functions
|
||||
*
|
||||
* Copyright 2000 Andreas Mohr for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* FIXME:
|
||||
* - return values ???
|
||||
* - this should be reimplemented at some point to have its own
|
||||
* file parsing instead of using profile functions,
|
||||
* as some SETUPX exports probably demand that
|
||||
* (IpSaveRestorePosition, IpFindNextMatchLine, ...).
|
||||
*/
|
||||
|
||||
#include "setupapi_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
|
||||
|
||||
#define MAX_HANDLES 16384
|
||||
#define FIRST_HANDLE 32
|
||||
|
||||
static HINF handles[MAX_HANDLES];
|
||||
|
||||
|
||||
static RETERR16 alloc_hinf16( HINF hinf, HINF16 *hinf16 )
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_HANDLES; i++)
|
||||
{
|
||||
if (!handles[i])
|
||||
{
|
||||
handles[i] = hinf;
|
||||
*hinf16 = i + FIRST_HANDLE;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
return ERR_IP_OUT_OF_HANDLES;
|
||||
}
|
||||
|
||||
static HINF get_hinf( HINF16 hinf16 )
|
||||
{
|
||||
int idx = hinf16 - FIRST_HANDLE;
|
||||
if (idx < 0 || idx >= MAX_HANDLES) return 0;
|
||||
return handles[idx];
|
||||
}
|
||||
|
||||
|
||||
static HINF free_hinf16( HINF16 hinf16 )
|
||||
{
|
||||
HINF ret;
|
||||
int idx = hinf16 - FIRST_HANDLE;
|
||||
|
||||
if (idx < 0 || idx >= MAX_HANDLES) return 0;
|
||||
ret = handles[idx];
|
||||
handles[idx] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* convert last error code to a RETERR16 value */
|
||||
static RETERR16 get_last_error(void)
|
||||
{
|
||||
switch(GetLastError())
|
||||
{
|
||||
case ERROR_EXPECTED_SECTION_NAME:
|
||||
case ERROR_BAD_SECTION_NAME_LINE:
|
||||
case ERROR_SECTION_NAME_TOO_LONG: return ERR_IP_INVALID_SECT_NAME;
|
||||
case ERROR_SECTION_NOT_FOUND: return ERR_IP_SECT_NOT_FOUND;
|
||||
case ERROR_LINE_NOT_FOUND: return ERR_IP_LINE_NOT_FOUND;
|
||||
default: return IP_ERROR; /* FIXME */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* IpOpen (SETUPX.2)
|
||||
*
|
||||
*/
|
||||
RETERR16 WINAPI IpOpen16( LPCSTR filename, HINF16 *hinf16 )
|
||||
{
|
||||
HINF hinf = SetupOpenInfFileA( filename, NULL, INF_STYLE_WIN4, NULL );
|
||||
if (hinf == (HINF)INVALID_HANDLE_VALUE) return get_last_error();
|
||||
return alloc_hinf16( hinf, hinf16 );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* IpClose (SETUPX.4)
|
||||
*/
|
||||
RETERR16 WINAPI IpClose16( HINF16 hinf16 )
|
||||
{
|
||||
HINF hinf = free_hinf16( hinf16 );
|
||||
if (!hinf) return ERR_IP_INVALID_HINF;
|
||||
SetupCloseInfFile( hinf );
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* IpGetProfileString (SETUPX.210)
|
||||
*/
|
||||
RETERR16 WINAPI IpGetProfileString16( HINF16 hinf16, LPCSTR section, LPCSTR entry,
|
||||
LPSTR buffer, WORD buflen )
|
||||
{
|
||||
DWORD required_size;
|
||||
HINF hinf = get_hinf( hinf16 );
|
||||
|
||||
if (!hinf) return ERR_IP_INVALID_HINF;
|
||||
if (!SetupGetLineTextA( NULL, hinf, section, entry, buffer, buflen, &required_size ))
|
||||
return get_last_error();
|
||||
TRACE("%p: section %s entry %s ret %s\n",
|
||||
hinf, debugstr_a(section), debugstr_a(entry), debugstr_a(buffer) );
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GenFormStrWithoutPlaceHolders (SETUPX.103)
|
||||
*
|
||||
* ought to be pretty much implemented, I guess...
|
||||
*/
|
||||
void WINAPI GenFormStrWithoutPlaceHolders16( LPSTR dst, LPCSTR src, HINF16 hinf16 )
|
||||
{
|
||||
UNICODE_STRING srcW;
|
||||
HINF hinf = get_hinf( hinf16 );
|
||||
|
||||
if (!hinf) return;
|
||||
|
||||
if (!RtlCreateUnicodeStringFromAsciiz( &srcW, src )) return;
|
||||
PARSER_string_substA( hinf, srcW.Buffer, dst, MAX_INF_STRING_LENGTH );
|
||||
RtlFreeUnicodeString( &srcW );
|
||||
TRACE( "%s -> %s\n", debugstr_a(src), debugstr_a(dst) );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GenInstall (SETUPX.101)
|
||||
*
|
||||
* generic installer function for .INF file sections
|
||||
*
|
||||
* This is not perfect - patch whenever you can !
|
||||
*
|
||||
* wFlags == GENINSTALL_DO_xxx
|
||||
* e.g. NetMeeting:
|
||||
* first call GENINSTALL_DO_REGSRCPATH | GENINSTALL_DO_FILES,
|
||||
* second call GENINSTALL_DO_LOGCONFIG | CFGAUTO | INI2REG | REG | INI
|
||||
*/
|
||||
RETERR16 WINAPI GenInstall16( HINF16 hinf16, LPCSTR section, WORD genflags )
|
||||
{
|
||||
UINT flags = 0;
|
||||
HINF hinf = get_hinf( hinf16 );
|
||||
RETERR16 ret = OK;
|
||||
void *context;
|
||||
|
||||
if (!hinf) return ERR_IP_INVALID_HINF;
|
||||
|
||||
if (genflags & GENINSTALL_DO_FILES) flags |= SPINST_FILES;
|
||||
if (genflags & GENINSTALL_DO_INI) flags |= SPINST_INIFILES;
|
||||
if (genflags & GENINSTALL_DO_REG) flags |= SPINST_REGISTRY;
|
||||
if (genflags & GENINSTALL_DO_INI2REG) flags |= SPINST_INI2REG;
|
||||
if (genflags & GENINSTALL_DO_LOGCONFIG) flags |= SPINST_LOGCONFIG;
|
||||
if (genflags & GENINSTALL_DO_REGSRCPATH) FIXME( "unsupported flag: GENINSTALL_DO_REGSRCPATH\n" );
|
||||
if (genflags & GENINSTALL_DO_CFGAUTO) FIXME( "unsupported flag: GENINSTALL_DO_CFGAUTO\n" );
|
||||
if (genflags & GENINSTALL_DO_PERUSER) FIXME( "unsupported flag: GENINSTALL_DO_PERUSER\n" );
|
||||
|
||||
context = SetupInitDefaultQueueCallback( 0 );
|
||||
if (!SetupInstallFromInfSectionA( 0, hinf, section, flags, 0, NULL,
|
||||
SP_COPY_NEWER_OR_SAME, SetupDefaultQueueCallbackA,
|
||||
context, 0, 0 ))
|
||||
ret = get_last_error();
|
||||
|
||||
SetupTermDefaultQueueCallback( context );
|
||||
return ret;
|
||||
}
|
||||
@@ -805,7 +805,7 @@ static BOOL iterate_section_fields( HINF hinf, PCWSTR section, PCWSTR key,
|
||||
}
|
||||
ret = TRUE;
|
||||
done:
|
||||
if (buffer && buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
|
||||
if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1094,11 +1094,15 @@ void WINAPI InstallHinfSectionW( HWND hwnd, HINSTANCE handle, LPCWSTR cmdline, I
|
||||
hinf = SetupOpenInfFileW( path, NULL, INF_STYLE_WIN4, NULL );
|
||||
if (hinf == INVALID_HANDLE_VALUE) return;
|
||||
|
||||
callback_context = SetupInitDefaultQueueCallback( hwnd );
|
||||
SetupInstallFromInfSectionW( hwnd, hinf, section, SPINST_ALL, NULL, NULL, SP_COPY_NEWER,
|
||||
SetupDefaultQueueCallbackW, callback_context,
|
||||
NULL, NULL );
|
||||
SetupTermDefaultQueueCallback( callback_context );
|
||||
if (SetupDiGetActualSectionToInstallW(
|
||||
hinf, section, section, sizeof(section)/sizeof(section[0]), NULL, NULL ))
|
||||
{
|
||||
callback_context = SetupInitDefaultQueueCallback( hwnd );
|
||||
SetupInstallFromInfSectionW( hwnd, hinf, section, SPINST_ALL, NULL, NULL, SP_COPY_NEWER,
|
||||
SetupDefaultQueueCallbackW, callback_context,
|
||||
NULL, NULL );
|
||||
SetupTermDefaultQueueCallback( callback_context );
|
||||
}
|
||||
SetupCloseInfFile( hinf );
|
||||
|
||||
/* FIXME: should check the mode and maybe reboot */
|
||||
|
||||
@@ -1,780 +0,0 @@
|
||||
/*
|
||||
* SetupAPI virtual copy operations
|
||||
*
|
||||
* Copyright 2001 Andreas Mohr
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* FIXME: we now rely on builtin setupapi.dll for dialog resources.
|
||||
* This is bad ! We ought to have 16bit resource handling working.
|
||||
*/
|
||||
|
||||
#include "setupapi_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
|
||||
|
||||
static FARPROC16 VCP_Proc = NULL;
|
||||
static LPARAM VCP_MsgRef = 0;
|
||||
|
||||
static BOOL VCP_opened = FALSE;
|
||||
|
||||
static VCPSTATUS vcp_status;
|
||||
|
||||
static HINSTANCE SETUPAPI_hInstance;
|
||||
|
||||
static WORD VCP_Callback( LPVOID obj, UINT16 msg, WPARAM16 wParam, LPARAM lParam, LPARAM lParamRef )
|
||||
{
|
||||
WORD args[8];
|
||||
DWORD ret = OK;
|
||||
if (VCP_Proc)
|
||||
{
|
||||
args[7] = HIWORD(obj);
|
||||
args[6] = LOWORD(obj);
|
||||
args[5] = msg;
|
||||
args[4] = wParam;
|
||||
args[3] = HIWORD(lParam);
|
||||
args[2] = LOWORD(lParam);
|
||||
args[1] = HIWORD(lParamRef);
|
||||
args[0] = LOWORD(lParamRef);
|
||||
WOWCallback16Ex( (DWORD)VCP_Proc, WCB16_PASCAL, sizeof(args), args, &ret );
|
||||
}
|
||||
return (WORD)ret;
|
||||
}
|
||||
|
||||
/****************************** VHSTR management ******************************/
|
||||
|
||||
/*
|
||||
* This is a totally braindead implementation for now;
|
||||
* I don't care about speed at all ! Size and implementation time
|
||||
* is much more important IMHO. I could have created some sophisticated
|
||||
* tree structure, but... what the hell ! :-)
|
||||
*/
|
||||
typedef struct {
|
||||
DWORD refcount;
|
||||
LPCSTR pStr;
|
||||
} VHSTR_STRUCT;
|
||||
|
||||
static VHSTR_STRUCT **vhstrlist = NULL;
|
||||
static VHSTR vhstr_alloc = 0;
|
||||
|
||||
#define VALID_VHSTR(x) ((x < vhstr_alloc) && (vhstrlist[x]) && (vhstrlist[x]->refcount))
|
||||
|
||||
/***********************************************************************
|
||||
* vsmStringAdd (SETUPX.207)
|
||||
*/
|
||||
VHSTR WINAPI vsmStringAdd16(LPCSTR lpszName)
|
||||
{
|
||||
VHSTR n;
|
||||
VHSTR index = 0xffff;
|
||||
HANDLE heap;
|
||||
|
||||
TRACE("add string '%s'\n", lpszName);
|
||||
/* search whether string already inserted */
|
||||
TRACE("searching for existing string...\n");
|
||||
for (n = 0; n < vhstr_alloc; n++)
|
||||
{
|
||||
if ((vhstrlist[n]) && (vhstrlist[n]->refcount))
|
||||
{
|
||||
TRACE("checking item: %d\n", n);
|
||||
if (!strcmp(vhstrlist[n]->pStr, lpszName))
|
||||
{
|
||||
TRACE("found\n");
|
||||
vhstrlist[n]->refcount++;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* hmm, not found yet, let's insert it */
|
||||
TRACE("inserting item\n");
|
||||
for (n = 0; n < vhstr_alloc; n++)
|
||||
{
|
||||
if ((!(vhstrlist[n])) || (!(vhstrlist[n]->refcount)))
|
||||
{
|
||||
index = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
heap = GetProcessHeap();
|
||||
if (n == vhstr_alloc) /* hmm, no free index found yet */
|
||||
{
|
||||
index = vhstr_alloc;
|
||||
vhstr_alloc += 20;
|
||||
|
||||
if (vhstrlist)
|
||||
vhstrlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, vhstrlist,
|
||||
sizeof(VHSTR_STRUCT *) * vhstr_alloc);
|
||||
else
|
||||
vhstrlist = HeapAlloc(heap, HEAP_ZERO_MEMORY,
|
||||
sizeof(VHSTR_STRUCT *) * vhstr_alloc);
|
||||
}
|
||||
if (index == 0xffff)
|
||||
return 0xffff; /* failure */
|
||||
if (!vhstrlist[index])
|
||||
vhstrlist[index] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VHSTR_STRUCT));
|
||||
vhstrlist[index]->refcount = 1;
|
||||
vhstrlist[index]->pStr = HeapAlloc(heap, 0, strlen(lpszName)+1);
|
||||
strcpy((LPSTR)vhstrlist[index]->pStr, lpszName);
|
||||
return index;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* vsmStringDelete (SETUPX.206)
|
||||
*/
|
||||
INT16 WINAPI vsmStringDelete16(VHSTR vhstr)
|
||||
{
|
||||
if (VALID_VHSTR(vhstr))
|
||||
{
|
||||
vhstrlist[vhstr]->refcount--;
|
||||
if (!vhstrlist[vhstr]->refcount)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, (LPSTR)vhstrlist[vhstr]->pStr);
|
||||
vhstrlist[vhstr]->pStr = NULL;
|
||||
}
|
||||
return VCPN_OK;
|
||||
}
|
||||
|
||||
/* string not found */
|
||||
return VCPN_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* vsmStringFind() - not exported from a standard SETUPX.DLL, it seems
|
||||
*/
|
||||
VHSTR WINAPI vsmStringFind16(LPCSTR lpszName)
|
||||
{
|
||||
WORD n;
|
||||
for (n = 0; n < vhstr_alloc; n++)
|
||||
if ((vhstrlist[n]) && (vhstrlist[n]->refcount) && (!strcmp(vhstrlist[n]->pStr, lpszName)))
|
||||
return n;
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* vsmGetStringName (SETUPX.205)
|
||||
*
|
||||
* Pretty correct, I guess
|
||||
*/
|
||||
INT16 WINAPI vsmGetStringName16(VHSTR vhstr, LPSTR lpszBuffer, int cbBuffer)
|
||||
{
|
||||
if (VALID_VHSTR(vhstr))
|
||||
{
|
||||
int len = strlen(vhstrlist[vhstr]->pStr)+1;
|
||||
if (cbBuffer >= len)
|
||||
{
|
||||
if (lpszBuffer)
|
||||
strcpy(lpszBuffer, vhstrlist[vhstr]->pStr);
|
||||
return len;
|
||||
}
|
||||
}
|
||||
return VCPN_FAIL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* vsmStringCompare (not exported from a standard SETUPX.DLL, it seems)
|
||||
*/
|
||||
INT16 WINAPI vsmStringCompare16(VHSTR vhstrA, VHSTR vhstrB)
|
||||
{
|
||||
if ((!VALID_VHSTR(vhstrA)) || (!VALID_VHSTR(vhstrB)))
|
||||
return VCPN_FAIL; /* correct ? */
|
||||
return strcmp(vhstrlist[vhstrA]->pStr, vhstrlist[vhstrB]->pStr);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* vsmGetStringRawName (SETUPX.208)
|
||||
*/
|
||||
LPCSTR WINAPI vsmGetStringRawName16(VHSTR vhstr)
|
||||
{
|
||||
return (VALID_VHSTR(vhstr)) ? vhstrlist[vhstr]->pStr : NULL;
|
||||
}
|
||||
|
||||
|
||||
/***************************** VIRTNODE management ****************************/
|
||||
static LPVIRTNODE *pvnlist = NULL;
|
||||
static DWORD vn_num = 0;
|
||||
static DWORD vn_last = 0;
|
||||
|
||||
static RETERR16 VCP_VirtnodeCreate(LPVCPFILESPEC vfsSrc, LPVCPFILESPEC vfsDst, WORD fl, LPARAM lParam, LPEXPANDVTBL lpExpandVtbl)
|
||||
{
|
||||
HANDLE heap;
|
||||
LPVIRTNODE lpvn;
|
||||
RETERR16 cbres;
|
||||
|
||||
while (vn_last < vn_num)
|
||||
{
|
||||
if (pvnlist[vn_last] == NULL)
|
||||
break;
|
||||
vn_last++;
|
||||
}
|
||||
heap = GetProcessHeap();
|
||||
if (vn_last == vn_num)
|
||||
{
|
||||
vn_num += 20;
|
||||
if (pvnlist)
|
||||
pvnlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, pvnlist,
|
||||
sizeof(LPVIRTNODE *) * vn_num);
|
||||
else
|
||||
pvnlist = HeapAlloc(heap, HEAP_ZERO_MEMORY,
|
||||
sizeof(LPVIRTNODE *) * vn_num);
|
||||
}
|
||||
pvnlist[vn_last] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VIRTNODE));
|
||||
lpvn = pvnlist[vn_last];
|
||||
vn_last++;
|
||||
|
||||
lpvn->cbSize = sizeof(VIRTNODE);
|
||||
|
||||
if (vfsSrc)
|
||||
memcpy(&lpvn->vfsSrc, vfsSrc, sizeof(VCPFILESPEC));
|
||||
|
||||
if (vfsDst)
|
||||
memcpy(&lpvn->vfsDst, vfsDst, sizeof(VCPFILESPEC));
|
||||
|
||||
lpvn->fl = fl;
|
||||
lpvn->lParam = lParam;
|
||||
lpvn->lpExpandVtbl = lpExpandVtbl;
|
||||
|
||||
lpvn->vhstrDstFinalName = 0xffff; /* FIXME: what is this ? */
|
||||
|
||||
cbres = VCP_Callback(lpvn, VCPM_NODECREATE, 0, 0, VCP_MsgRef);
|
||||
lpvn->fl |= VFNL_CREATED;
|
||||
cbres = VCP_Callback(lpvn, VCPM_NODEACCEPT, 0, 0, VCP_MsgRef);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static BOOL VCP_VirtnodeDelete(LPVIRTNODE lpvnDel)
|
||||
{
|
||||
DWORD n;
|
||||
RETERR16 cbres;
|
||||
|
||||
for (n = 0; n < vn_last; n++)
|
||||
{
|
||||
if (pvnlist[n] == lpvnDel)
|
||||
{
|
||||
cbres = VCP_Callback(lpvnDel, VCPM_NODEDESTROY, 0, 0, VCP_MsgRef);
|
||||
HeapFree(GetProcessHeap(), 0, lpvnDel);
|
||||
pvnlist[n] = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* VcpOpen (SETUPX.200)
|
||||
*
|
||||
* Sets up a virtual copy operation.
|
||||
* This means that functions such as GenInstall()
|
||||
* create a VIRTNODE struct for every file to be touched in a .INF file
|
||||
* instead of actually touching the file.
|
||||
* The actual copy/move/rename gets started when VcpClose or
|
||||
* VcpFlush is called; several different callbacks are made
|
||||
* (copy, rename, open, close, version conflicts, ...) on every file copied.
|
||||
*/
|
||||
RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef)
|
||||
{
|
||||
TRACE("(%p, %08lx)\n", vifproc, lparamMsgRef);
|
||||
if (VCP_opened)
|
||||
return ERR_VCP_BUSY;
|
||||
|
||||
VCP_Proc = (FARPROC16)vifproc;
|
||||
VCP_MsgRef = lparamMsgRef;
|
||||
|
||||
/* load SETUPAPI needed for dialog resources etc. */
|
||||
SETUPAPI_hInstance = GetModuleHandleA("setupapi.dll");
|
||||
if (!SETUPAPI_hInstance)
|
||||
{
|
||||
ERR("Could not load sibling setupapi.dll\n");
|
||||
return ERR_VCP_NOMEM;
|
||||
}
|
||||
VCP_opened = TRUE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* VcpQueueCopy [SETUPX.13]
|
||||
*
|
||||
* lpExpandVtbl seems to be deprecated.
|
||||
* fl are the CNFL_xxx and VNFL_xxx flags.
|
||||
* lParam are the VNLP_xxx flags.
|
||||
*/
|
||||
RETERR16 WINAPI VcpQueueCopy16(
|
||||
LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
|
||||
LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
|
||||
LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
|
||||
LPEXPANDVTBL lpExpandVtbl,
|
||||
WORD fl, LPARAM lParam
|
||||
)
|
||||
{
|
||||
VCPFILESPEC vfsSrc, vfsDst;
|
||||
|
||||
if (!VCP_opened)
|
||||
return ERR_VCP_NOTOPEN;
|
||||
|
||||
TRACE("srcdir: %s, srcfile: %s, dstdir: %s, dstfile: %s\n",
|
||||
lpszSrcDir, lpszSrcFileName, lpszDstDir, lpszDstFileName);
|
||||
|
||||
TRACE("ldidSrc == %d, ldidDst == %d\n", ldidSrc, ldidDst);
|
||||
|
||||
vfsSrc.ldid = ldidSrc;
|
||||
vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
|
||||
vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);
|
||||
|
||||
vfsDst.ldid = ldidDst;
|
||||
vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
|
||||
vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
|
||||
|
||||
return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, fl, lParam,
|
||||
lpExpandVtbl);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* VcpQueueDelete [SETUPX.17]
|
||||
*
|
||||
* Is lParamRef the same as lParam in VcpQueueCopy ?
|
||||
* Damn docu !! Err... which docu ?
|
||||
*/
|
||||
RETERR16 WINAPI VcpQueueDelete16(
|
||||
LPCSTR lpszDstFileName,
|
||||
LPCSTR lpszDstDir,
|
||||
LOGDISKID16 ldidDst,
|
||||
LPARAM lParamRef
|
||||
)
|
||||
{
|
||||
VCPFILESPEC vfsDst;
|
||||
|
||||
if (!VCP_opened)
|
||||
return ERR_VCP_NOTOPEN;
|
||||
|
||||
vfsDst.ldid = ldidDst;
|
||||
vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
|
||||
vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
|
||||
|
||||
return VCP_VirtnodeCreate(NULL, &vfsDst, VNFL_DELETE, lParamRef, 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* VcpQueueRename [SETUPX.204]
|
||||
*
|
||||
*/
|
||||
RETERR16 WINAPI VcpQueueRename16(
|
||||
LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
|
||||
LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
|
||||
LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
VCPFILESPEC vfsSrc, vfsDst;
|
||||
|
||||
if (!VCP_opened)
|
||||
return ERR_VCP_NOTOPEN;
|
||||
|
||||
vfsSrc.ldid = ldidSrc;
|
||||
vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
|
||||
vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);
|
||||
|
||||
vfsDst.ldid = ldidDst;
|
||||
vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
|
||||
vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
|
||||
|
||||
return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, VNFL_RENAME, lParam,
|
||||
0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* VcpEnumFiles (SETUPX.@)
|
||||
*/
|
||||
INT16 WINAPI VcpEnumFiles(VCPENUMPROC vep, LPARAM lParamRef)
|
||||
{
|
||||
WORD n;
|
||||
|
||||
for (n = 0; n < vn_last; n++)
|
||||
vep(pvnlist[n], lParamRef);
|
||||
|
||||
return 0; /* FIXME: return value ? */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* VcpExplain (SETUPX.411)
|
||||
*/
|
||||
LPCSTR WINAPI VcpExplain16(LPVIRTNODE lpVn, DWORD dwWhat)
|
||||
{
|
||||
static char buffer[MAX_PATH]; /* FIXME: is this how it's done ? */
|
||||
buffer[0] = '\0';
|
||||
switch (dwWhat)
|
||||
{
|
||||
case VCPEX_SRC_FULL:
|
||||
case VCPEX_DST_FULL:
|
||||
{
|
||||
LPVCPFILESPEC lpvfs =
|
||||
(dwWhat == VCPEX_SRC_FULL) ? &lpVn->vfsSrc : &lpVn->vfsDst;
|
||||
|
||||
/* if we have an ldid, use it, otherwise use the string */
|
||||
/* from the vhstrlist array */
|
||||
if (lpvfs->ldid != 0xffff)
|
||||
CtlGetLddPath16(lpvfs->ldid, buffer);
|
||||
else
|
||||
strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrDir));
|
||||
|
||||
strcat(buffer, "\\");
|
||||
strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrFileName));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("%ld unimplemented !\n", dwWhat);
|
||||
strcpy(buffer, "Unknown error");
|
||||
break;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static RETERR16 VCP_CheckPaths(void)
|
||||
{
|
||||
DWORD n;
|
||||
LPVIRTNODE lpvn;
|
||||
RETERR16 cbres;
|
||||
|
||||
cbres = VCP_Callback(&vcp_status, VCPM_VSTATPATHCHECKSTART, 0, 0, VCP_MsgRef);
|
||||
for (n = 0; n < vn_num; n++)
|
||||
{
|
||||
lpvn = pvnlist[n];
|
||||
if (!lpvn) continue;
|
||||
/* FIXME: check paths of all VIRTNODEs here ! */
|
||||
cbres = VCP_Callback(&lpvn->vfsDst, VCPM_CHECKPATH, 0, (DWORD)lpvn, VCP_MsgRef);
|
||||
}
|
||||
cbres = VCP_Callback(&vcp_status, VCPM_VSTATPATHCHECKEND, 0, 0, VCP_MsgRef);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static RETERR16 VCP_CopyFiles(void)
|
||||
{
|
||||
char fn_src[MAX_PATH], fn_dst[MAX_PATH];
|
||||
RETERR16 res = OK, cbres;
|
||||
DWORD n;
|
||||
LPVIRTNODE lpvn;
|
||||
|
||||
cbres = VCP_Callback(&vcp_status, VCPM_VSTATCOPYSTART, 0, 0, VCP_MsgRef);
|
||||
for (n = 0; n < vn_num; n++)
|
||||
{
|
||||
lpvn = pvnlist[n];
|
||||
if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_COPY)) continue;
|
||||
/* FIXME: need to send VCPM_VSTATNEWDISK notification sometimes */
|
||||
strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
|
||||
strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
|
||||
/* FIXME: what is this VCPM_VSTATWRITE here for ?
|
||||
* I guess it's to signal successful destination file creation */
|
||||
cbres = VCP_Callback(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
|
||||
|
||||
/* FIXME: need to do the file copy in small chunks for notifications */
|
||||
TRACE("copying '%s' to '%s'\n", fn_src, fn_dst);
|
||||
/* perform the file copy */
|
||||
if (!(CopyFileA(fn_src, fn_dst,
|
||||
(lpvn->fl & VNLP_COPYIFEXISTS) ? FALSE : TRUE )))
|
||||
{
|
||||
ERR("error copying, src: %s -> dst: %s\n", fn_src, fn_dst);
|
||||
res = ERR_VCP_IOFAIL;
|
||||
}
|
||||
|
||||
vcp_status.prgFileRead.dwSoFar++;
|
||||
cbres = VCP_Callback(&vcp_status, VCPM_VSTATREAD, 0, 0, VCP_MsgRef);
|
||||
vcp_status.prgFileWrite.dwSoFar++;
|
||||
cbres = VCP_Callback(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
|
||||
}
|
||||
|
||||
cbres = VCP_Callback(&vcp_status, VCPM_VSTATCOPYEND, 0, 0, VCP_MsgRef);
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* VcpFlush - internal (not exported), but documented
|
||||
*
|
||||
* VNFL_NOW is used for VcpFlush.
|
||||
*/
|
||||
RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* VcpClose (SETUPX.201)
|
||||
*
|
||||
* Does callbacks (-> vifproc) with VCPM_VSTATCLOSESTART,
|
||||
* VCPM_VSTATCLOSEEND.
|
||||
*
|
||||
* fl gets VCPFL_xxx flags to indicate what to do with the
|
||||
* VIRTNODEs (files to mess with) created by e.g. GenInstall()
|
||||
*/
|
||||
RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest)
|
||||
{
|
||||
RETERR16 res = OK;
|
||||
WORD cbres = VCPN_PROCEED;
|
||||
|
||||
TRACE("(%04x, '%s')\n", fl, lpszBackupDest);
|
||||
|
||||
/* FIXME: needs to sort virtnodes in case VCPFL_INSPECIFIEDORDER
|
||||
* is not set. This is done by VCP_Callback(VCPM_NODECOMPARE) */
|
||||
|
||||
TRACE("#1\n");
|
||||
memset(&vcp_status, 0, sizeof(VCPSTATUS));
|
||||
/* yes, vcp_status.cbSize is 0 ! */
|
||||
TRACE("#2\n");
|
||||
cbres = VCP_Callback(&vcp_status, VCPM_VSTATCLOSESTART, 0, 0, VCP_MsgRef);
|
||||
TRACE("#3\n");
|
||||
|
||||
res = VCP_CheckPaths();
|
||||
TRACE("#4\n");
|
||||
if (res != OK)
|
||||
return res; /* is this ok ? */
|
||||
VCP_CopyFiles();
|
||||
|
||||
TRACE("#5\n");
|
||||
cbres = VCP_Callback(&vcp_status, VCPM_VSTATCLOSEEND, 0, 0, VCP_MsgRef);
|
||||
TRACE("#6\n");
|
||||
VCP_Proc = NULL;
|
||||
VCP_opened = FALSE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static RETERR16 VCP_RenameFiles(void)
|
||||
{
|
||||
char fn_src[MAX_PATH], fn_dst[MAX_PATH];
|
||||
RETERR16 res = OK, cbres;
|
||||
DWORD n;
|
||||
LPVIRTNODE lpvn;
|
||||
|
||||
cbres = VCP_Callback(&vcp_status, VCPM_VSTATRENAMESTART, 0, 0, VCP_MsgRef);
|
||||
for (n = 0; n < vn_num; n++)
|
||||
{
|
||||
lpvn = pvnlist[n];
|
||||
if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_RENAME)) continue;
|
||||
strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
|
||||
strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
|
||||
cbres = VCP_Callback(&lpvn->vfsDst, VCPM_FILEOPENOUT, 0, (LPARAM)lpvn, VCP_MsgRef);
|
||||
if (!(MoveFileExA(fn_src, fn_dst, MOVEFILE_REPLACE_EXISTING)))
|
||||
res = ERR_VCP_IOFAIL;
|
||||
else
|
||||
VCP_VirtnodeDelete(lpvn);
|
||||
}
|
||||
cbres = VCP_Callback(&vcp_status, VCPM_VSTATRENAMEEND, 0, 0, VCP_MsgRef);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* vcpDefCallbackProc (SETUPX.202)
|
||||
*/
|
||||
RETERR16 WINAPI vcpDefCallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
|
||||
LPARAM lParam, LPARAM lParamRef)
|
||||
{
|
||||
static int count = 0;
|
||||
if (count < 10)
|
||||
FIXME("(%p, %04x, %04x, %08lx, %08lx) - what to do here ?\n",
|
||||
lpvObj, uMsg, wParam, lParam, lParamRef);
|
||||
count++;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/********************* point-and-click stuff from here ***********************/
|
||||
|
||||
static HWND hDlgCopy = 0;
|
||||
static HKEY hKeyFiles = 0, hKeyRename = 0, hKeyConflict = 0;
|
||||
static char BackupDir[12];
|
||||
|
||||
static INT_PTR CALLBACK VCP_UI_FileCopyDlgProc(HWND hWndDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
INT_PTR retval = FALSE;
|
||||
|
||||
if (iMsg == WM_INITDIALOG)
|
||||
{
|
||||
ShowWindow(hWndDlg, SW_SHOWNORMAL);
|
||||
UpdateWindow(hWndDlg);
|
||||
retval = TRUE;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static BOOL VCP_UI_GetDialogTemplate(LPCVOID *template32)
|
||||
{
|
||||
HRSRC hResInfo;
|
||||
HGLOBAL hDlgTmpl32;
|
||||
|
||||
if (!(hResInfo = FindResourceA(SETUPAPI_hInstance, MAKEINTRESOURCEA(COPYFILEDLGORD), (LPSTR)RT_DIALOG)))
|
||||
return FALSE;
|
||||
if (!(hDlgTmpl32 = LoadResource(SETUPAPI_hInstance, hResInfo )) ||
|
||||
!(*template32 = LockResource( hDlgTmpl32 )))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static LRESULT WINAPI
|
||||
VCP_UI_FileCopyWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (uMsg != WM_CREATE)
|
||||
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
return 0;
|
||||
default:
|
||||
FIXME("%04x: unhandled.\n", uMsg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void VCP_UI_RegisterProgressClass(void)
|
||||
{
|
||||
static BOOL registered = FALSE;
|
||||
WNDCLASSA wndClass;
|
||||
|
||||
if (registered)
|
||||
return;
|
||||
|
||||
registered = TRUE;
|
||||
ZeroMemory (&wndClass, sizeof(WNDCLASSA));
|
||||
wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
|
||||
wndClass.lpfnWndProc = VCP_UI_FileCopyWndProc;
|
||||
wndClass.cbClsExtra = 0;
|
||||
wndClass.cbWndExtra = 0;
|
||||
wndClass.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
|
||||
wndClass.hbrBackground = NULL;
|
||||
wndClass.lpszClassName = "setupx_progress";
|
||||
|
||||
RegisterClassA (&wndClass);
|
||||
}
|
||||
|
||||
static RETERR16 VCP_UI_NodeCompare(LPVIRTNODE vn1, LPVIRTNODE vn2)
|
||||
{
|
||||
LPCSTR file1, file2;
|
||||
file1 = vsmGetStringRawName16(vn1->vfsSrc.vhstrFileName);
|
||||
file2 = vsmGetStringRawName16(vn2->vfsSrc.vhstrFileName);
|
||||
return (RETERR16)strcmp(file1, file2);
|
||||
}
|
||||
|
||||
static RETERR16 VCP_UI_CopyStart(void)
|
||||
{
|
||||
LPCVOID template32;
|
||||
char buf[256]; /* plenty */
|
||||
BOOL dirty;
|
||||
DWORD len;
|
||||
|
||||
/* FIXME: should be registered at DLL startup instead */
|
||||
VCP_UI_RegisterProgressClass();
|
||||
if (!(VCP_UI_GetDialogTemplate(&template32)))
|
||||
return VCPN_FAIL;
|
||||
|
||||
if (vn_num > 10) /* hack */
|
||||
{
|
||||
hDlgCopy = CreateDialogIndirectParamA(SETUPAPI_hInstance, template32, 0,
|
||||
VCP_UI_FileCopyDlgProc, 0);
|
||||
if (!hDlgCopy)
|
||||
return VCPN_FAIL;
|
||||
SetDlgItemTextA(hDlgCopy, SOURCESTRORD, "Scanning ...");
|
||||
SetDlgItemTextA(hDlgCopy, DESTSTRORD, "NOT_IMPLEMENTED_YET");
|
||||
}
|
||||
strcpy(buf, REG_INSTALLEDFILES);
|
||||
if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyFiles))
|
||||
return VCPN_FAIL;
|
||||
strcat(buf, REGPART_RENAME);
|
||||
if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyRename))
|
||||
return VCPN_FAIL;
|
||||
if (RegCreateKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT, &hKeyConflict))
|
||||
return VCPN_FAIL;
|
||||
len = 1;
|
||||
if (!(RegQueryValueExA(hKeyConflict, "Dirty", NULL, 0, (LPBYTE)&dirty, &len)))
|
||||
{
|
||||
/* FIXME: what does SETUPX.DLL do in this case ? */
|
||||
MESSAGE("Warning: another program using SETUPX is already running ! Failed.\n");
|
||||
return VCPN_FAIL;
|
||||
}
|
||||
dirty = TRUE;
|
||||
if (RegSetValueExA(hKeyConflict, "Dirty", 0, REG_BINARY, (LPBYTE)&dirty, 1))
|
||||
return VCPN_FAIL;
|
||||
len = 12;
|
||||
if (!(RegQueryValueExA(hKeyConflict, "BackupDirectory", NULL, 0, (LPBYTE)BackupDir, &len)))
|
||||
strcpy(BackupDir, "VCM");
|
||||
|
||||
/* create C:\WINDOWS\[BackupDir] and set registry key to it */
|
||||
GetWindowsDirectoryA(buf, 256);
|
||||
strcat(buf, "\\");
|
||||
strcat(buf, BackupDir);
|
||||
if (!(CreateDirectoryA(buf, NULL)))
|
||||
return VCPN_FAIL;
|
||||
if (RegSetValueExA(hKeyConflict, "BackupDirectory", 0, REG_SZ, (LPBYTE)buf, strlen(buf)+1))
|
||||
return VCPN_FAIL;
|
||||
RegCloseKey(hKeyConflict);
|
||||
|
||||
return VCPN_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* vcpUICallbackProc (SETUPX.213)
|
||||
*/
|
||||
RETERR16 WINAPI vcpUICallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
|
||||
LPARAM lParam, LPARAM lParamRef)
|
||||
{
|
||||
static int count = 0;
|
||||
RETERR16 res = VCPN_OK, cbres;
|
||||
|
||||
if (count < 5)
|
||||
FIXME("(%p, %04x, %04x, %08lx, %08lx) - semi-stub\n",
|
||||
lpvObj, uMsg, wParam, lParam, lParamRef);
|
||||
count++;
|
||||
switch (uMsg)
|
||||
{
|
||||
/* unused messages, it seems */
|
||||
case VCPM_DISKPREPINFO:
|
||||
|
||||
case VCPM_FILENEEDED:
|
||||
|
||||
case VCPM_NODECREATE:
|
||||
case VCPM_NODEACCEPT:
|
||||
|
||||
case VCPM_VSTATCLOSESTART:
|
||||
case VCPM_VSTATPATHCHECKSTART:
|
||||
case VCPM_VSTATPATHCHECKEND:
|
||||
|
||||
case VCPM_CHECKPATH:
|
||||
break;
|
||||
|
||||
/* the real stuff */
|
||||
case VCPM_NODECOMPARE:
|
||||
res = VCP_UI_NodeCompare((LPVIRTNODE)lpvObj, (LPVIRTNODE)lParam);
|
||||
break;
|
||||
case VCPM_VSTATREAD:
|
||||
break;
|
||||
case VCPM_VSTATWRITE:
|
||||
cbres = VCP_Callback(&vcp_status, VCPM_DISKPREPINFO, 0, 0, VCP_MsgRef);
|
||||
break;
|
||||
case VCPM_VSTATCLOSEEND:
|
||||
RegCloseKey(hKeyFiles);
|
||||
RegCloseKey(hKeyRename);
|
||||
RegDeleteKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT);
|
||||
break;
|
||||
case VCPM_VSTATCOPYSTART:
|
||||
res = VCP_UI_CopyStart();
|
||||
break;
|
||||
case VCPM_VSTATCOPYEND:
|
||||
if (hDlgCopy) DestroyWindow(hDlgCopy);
|
||||
break;
|
||||
default:
|
||||
FIXME("unhandled msg 0x%04x\n", uMsg);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
Reference in New Issue
Block a user