- fix inf file open/close
- do NOT return handles based on list offset - we might want to use HEAP_strdupA instead of assigning string pointers... - implement (more or less) GenFormStrWithoutPlaceholders
This commit is contained in:
parent
ee35e72771
commit
e826f27331
|
@ -7,15 +7,15 @@
|
|||
#include "debugtools.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "heap.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "setupx16.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(setupx);
|
||||
|
||||
WORD InfNumEntries = 0;
|
||||
INF_HANDLE *InfList = NULL;
|
||||
|
||||
#define GET_INF_ENTRY(x) ((InfList - x)/4)
|
||||
INF_FILE *InfList = NULL;
|
||||
HINF16 IP_curr_handle = 0;
|
||||
|
||||
RETERR16 IP_OpenInf(LPCSTR lpInfFileName, HINF16 *lphInf)
|
||||
{
|
||||
|
@ -24,25 +24,45 @@ RETERR16 IP_OpenInf(LPCSTR lpInfFileName, HINF16 *lphInf)
|
|||
if (!lphInf)
|
||||
return IP_ERROR;
|
||||
|
||||
/* this could be improved by checking for already freed handles */
|
||||
if (IP_curr_handle == 0xffff)
|
||||
return ERR_IP_OUT_OF_HANDLES;
|
||||
|
||||
if (hFile != HFILE_ERROR16)
|
||||
{
|
||||
InfList = HeapReAlloc(GetProcessHeap(), 0, InfList, InfNumEntries+1);
|
||||
InfList[InfNumEntries].hInf = IP_curr_handle++;
|
||||
InfList[InfNumEntries].hInfFile = hFile;
|
||||
InfList[InfNumEntries].lpInfFileName = lpInfFileName;
|
||||
InfList[InfNumEntries].lpInfFileName = HEAP_strdupA(GetProcessHeap(), 0, lpInfFileName);
|
||||
*lphInf = InfList[InfNumEntries].hInf;
|
||||
InfNumEntries++;
|
||||
*lphInf = &InfList[InfNumEntries-1] - InfList;
|
||||
TRACE("ret handle %d.\n", *lphInf);
|
||||
return OK;
|
||||
}
|
||||
*lphInf = 0xffff;
|
||||
return ERR_IP_INVALID_INFFILE;
|
||||
}
|
||||
|
||||
BOOL IP_FindInf(HINF16 hInf, WORD *ret)
|
||||
{
|
||||
WORD n;
|
||||
|
||||
for (n=0; n < InfNumEntries; n++)
|
||||
if (InfList[n].hInf == hInf)
|
||||
{
|
||||
*ret = n;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
LPCSTR IP_GetFileName(HINF16 hInf)
|
||||
{
|
||||
if ((hInf <= (InfNumEntries*sizeof(INF_HANDLE *)))
|
||||
&& ((hInf & 3) == 0)) /* aligned ? */
|
||||
WORD n;
|
||||
if (IP_FindInf(hInf, &n))
|
||||
{
|
||||
return InfList[hInf/4].lpInfFileName;
|
||||
return InfList[n].lpInfFileName;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -50,17 +70,18 @@ LPCSTR IP_GetFileName(HINF16 hInf)
|
|||
RETERR16 IP_CloseInf(HINF16 hInf)
|
||||
{
|
||||
int i;
|
||||
WORD n;
|
||||
HFILE16 res = ERR_IP_INVALID_HINF;
|
||||
|
||||
if ((hInf <= (InfNumEntries*sizeof(INF_HANDLE *)))
|
||||
&& ((hInf & 3) == 0)) /* aligned ? */
|
||||
if (IP_FindInf(hInf, &n))
|
||||
{
|
||||
_lclose16(InfList[hInf/4].hInfFile);
|
||||
res = OK;
|
||||
for (i=hInf/4; i < InfNumEntries-1; i++)
|
||||
_lclose16(InfList[n].hInfFile);
|
||||
HeapFree(GetProcessHeap(), 0, InfList[n].lpInfFileName);
|
||||
for (i=n; i < InfNumEntries-1; i++)
|
||||
InfList[i] = InfList[i+1];
|
||||
InfNumEntries--;
|
||||
InfList = HeapReAlloc(GetProcessHeap(), 0, InfList, InfNumEntries);
|
||||
res = OK;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -88,6 +109,7 @@ RETERR16 WINAPI IpClose16(HINF16 hInf)
|
|||
*/
|
||||
RETERR16 WINAPI IpGetProfileString16(HINF16 hInf, LPCSTR section, LPCSTR entry, LPSTR buffer, WORD buflen)
|
||||
{
|
||||
TRACE("'%s': section '%s' entry '%s'\n", IP_GetFileName(hInf), section, entry);
|
||||
GetPrivateProfileString16(section, entry, "", buffer, buflen, IP_GetFileName(hInf));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef __WINE_SETUPX16_H
|
||||
#define __WINE_SETUPX16_H
|
||||
#ifndef __SETUPX16_H
|
||||
#define __SETUPX16_H
|
||||
|
||||
#include "wine/windef16.h"
|
||||
|
||||
|
@ -31,12 +31,47 @@ enum _IP_ERR {
|
|||
ERR_IP_INVALID_INFTYPE
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
HFILE16 hInfFile;
|
||||
LPCSTR lpInfFileName;
|
||||
} INF_HANDLE;
|
||||
/* logical disk identifiers (LDID) */
|
||||
#define LDID_NULL 0
|
||||
#define LDID_ABSOLUTE ((UINT)-1)
|
||||
#define LDID_SRCPATH 1 /* setup source path */
|
||||
#define LDID_SETUPTEMP 2 /* setup temp dir */
|
||||
#define LDID_UNINSTALL 3 /* uninstall dir */
|
||||
#define LDID_BACKUP 4 /* backup dir */
|
||||
#define LDID_SETUPSCRATCH 5 /* setup scratch dir */
|
||||
#define LDID_WIN 10 /* win dir */
|
||||
#define LDID_SYS 11 /* win system dir */
|
||||
#define LDID_IOS 12 /* win Iosubsys dir */
|
||||
#define LDID_CMD 13 /* win command dir */
|
||||
#define LDID_CPL 14 /* win control panel dir */
|
||||
#define LDID_PRINT 15 /* win printer dir */
|
||||
#define LDID_MAIL 16 /* win mail dir */
|
||||
#define LDID_INF 17 /* win inf dir */
|
||||
#define LDID_HELP 18 /* win help dir */
|
||||
#define LDID_WINADMIN 19 /* admin dir */
|
||||
#define LDID_FONTS 20 /* win fonts dir */
|
||||
#define LDID_VIEWERS 21 /* win viewers dir */
|
||||
#define LDID_VMM32 22 /* win VMM32 dir */
|
||||
#define LDID_COLOR 23 /* win color mngment dir */
|
||||
#define LDID_APPS 24 /* win apps dir */
|
||||
#define LDID_SHARED 25 /* win shared dir */
|
||||
#define LDID_WINBOOT 26 /* guaranteed win boot drive */
|
||||
#define LDID_MACHINE 27 /* machine specific files */
|
||||
#define LDID_HOST_WINBOOT 28
|
||||
#define LDID_BOOT 30 /* boot drive root dir */
|
||||
#define LDID_BOOT_HOST 31 /* boot drive host root dir */
|
||||
#define LDID_OLD_WINBOOT 32 /* root subdir */
|
||||
#define LDID_OLD_WIN 33 /* old windows dir */
|
||||
|
||||
extern INF_HANDLE *InfList;
|
||||
typedef struct {
|
||||
HINF16 hInf;
|
||||
HFILE16 hInfFile;
|
||||
LPSTR lpInfFileName;
|
||||
} INF_FILE;
|
||||
|
||||
extern INF_FILE *InfList;
|
||||
extern WORD InfNumEntries;
|
||||
|
||||
#endif /* __WINE_SETUPX16_H */
|
||||
extern LPCSTR IP_GetFileName(HINF16 hInf);
|
||||
|
||||
#endif /* __SETUPX16_H */
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* See:
|
||||
* http://www.geocities.com/SiliconValley/Network/5317/drivers.html
|
||||
* http://willemer.de/informatik/windows/inf_info.htm (German)
|
||||
* http://www.microsoft.com/ddk/ddkdocs/win98ddk/devinst_12uw.htm
|
||||
* DDK: setupx.h
|
||||
* http://mmatrix.tripod.com/customsystemfolder/infsysntaxfull.html
|
||||
|
@ -15,9 +16,11 @@
|
|||
* Stuff tested with rs405deu.exe (German Acroread 4.05 setup)
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "winreg.h"
|
||||
#include "wine/winuser16.h"
|
||||
#include "setupx16.h"
|
||||
#include "winerror.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(setupx);
|
||||
|
@ -61,16 +64,306 @@ DWORD WINAPI InstallHinfSection16( HWND16 hwnd, HINSTANCE16 hinst, LPCSTR lpszCm
|
|||
return 0;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LPCSTR RegValName;
|
||||
LPCSTR StdString; /* fallback string; sub dir of windows directory */
|
||||
} LDID_DATA;
|
||||
|
||||
static LDID_DATA LDID_Data[34] =
|
||||
{
|
||||
{ /* 0 (LDID_NULL) -- not defined */
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{ /* 1 (LDID_SRCPATH) = source of installation. hmm, what to do here ? */
|
||||
"SourcePath", /* hmm, does SETUPX have to care about updating it ?? */
|
||||
NULL
|
||||
},
|
||||
{ /* 2 (LDID_SETUPTEMP) = setup temp dir */
|
||||
"SetupTempDir",
|
||||
NULL
|
||||
},
|
||||
{ /* 3 (LDID_UNINSTALL) = uninstall backup dir */
|
||||
"UninstallDir",
|
||||
NULL
|
||||
},
|
||||
{ /* 4 (LDID_BACKUP) = backup dir */
|
||||
"BackupDir",
|
||||
NULL
|
||||
},
|
||||
{ /* 5 (LDID_SETUPSCRATCH) = setup scratch dir */
|
||||
"SetupScratchDir",
|
||||
NULL
|
||||
},
|
||||
{ /* 6 -- not defined */
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{ /* 7 -- not defined */
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{ /* 8 -- not defined */
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{ /* 9 -- not defined */
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{ /* 10 (LDID_WIN) = windows dir */
|
||||
"WinDir",
|
||||
""
|
||||
},
|
||||
{ /* 11 (LDID_SYS) = system dir */
|
||||
"SysDir",
|
||||
NULL /* call GetSystemDirectory() instead */
|
||||
},
|
||||
{ /* 12 (LDID_IOS) = IOSubSys dir */
|
||||
NULL, /* FIXME: registry string ? */
|
||||
"SYSTEM\\IOSUBSYS"
|
||||
},
|
||||
{ /* 13 (LDID_CMD) = COMMAND dir */
|
||||
NULL, /* FIXME: registry string ? */
|
||||
"COMMAND"
|
||||
},
|
||||
{ /* 14 (LDID_CPL) = control panel dir */
|
||||
NULL,
|
||||
""
|
||||
},
|
||||
{ /* 15 (LDID_PRINT) = windows printer dir */
|
||||
NULL,
|
||||
"SYSTEM" /* correct ?? */
|
||||
},
|
||||
{ /* 16 (LDID_MAIL) = destination mail dir */
|
||||
NULL,
|
||||
""
|
||||
},
|
||||
{ /* 17 (LDID_INF) = INF dir */
|
||||
"SetupScratchDir", /* correct ? */
|
||||
"INF"
|
||||
},
|
||||
{ /* 18 (LDID_HELP) = HELP dir */
|
||||
NULL, /* ??? */
|
||||
"HELP"
|
||||
},
|
||||
{ /* 19 (LDID_WINADMIN) = Admin dir */
|
||||
"WinAdminDir",
|
||||
""
|
||||
},
|
||||
{ /* 20 (LDID_FONTS) = Fonts dir */
|
||||
NULL, /* ??? */
|
||||
"FONTS"
|
||||
},
|
||||
{ /* 21 (LDID_VIEWERS) = Viewers */
|
||||
NULL, /* ??? */
|
||||
"SYSTEM\\VIEWERS"
|
||||
},
|
||||
{ /* 22 (LDID_VMM32) = VMM32 dir */
|
||||
NULL, /* ??? */
|
||||
"SYSTEM\\VMM32"
|
||||
},
|
||||
{ /* 23 (LDID_COLOR) = ICM dir */
|
||||
"ICMPath",
|
||||
"SYSTEM\\COLOR"
|
||||
},
|
||||
{ /* 24 (LDID_APPS) = root of boot drive ? */
|
||||
"AppsDir",
|
||||
"C:\\"
|
||||
},
|
||||
{ /* 25 (LDID_SHARED) = shared dir */
|
||||
"SharedDir",
|
||||
""
|
||||
},
|
||||
{ /* 26 (LDID_WINBOOT) = Windows boot dir */
|
||||
"WinBootDir",
|
||||
""
|
||||
},
|
||||
{ /* 27 (LDID_MACHINE) = machine specific files */
|
||||
"MachineDir",
|
||||
NULL
|
||||
},
|
||||
{ /* 28 (LDID_HOST_WINBOOT) = Host Windows boot dir */
|
||||
"HostWinBootDir",
|
||||
NULL
|
||||
},
|
||||
{ /* 29 -- not defined */
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{ /* 30 (LDID_BOOT) = Root of boot drive */
|
||||
"BootDir",
|
||||
NULL
|
||||
},
|
||||
{ /* 31 (LDID_BOOT_HOST) = Root of boot drive host */
|
||||
"BootHost",
|
||||
NULL
|
||||
},
|
||||
{ /* 32 (LDID_OLD_WINBOOT) = subdir of root */
|
||||
"OldWinBootDir",
|
||||
NULL
|
||||
},
|
||||
{ /* 33 (LDID_OLD_WIN) = old win dir */
|
||||
"OldWinDir",
|
||||
NULL
|
||||
}
|
||||
/* the rest (34-38) isn't too interesting, so I'll forget about it */
|
||||
};
|
||||
|
||||
/*
|
||||
* GenFormStrWithoutPlaceholders
|
||||
*
|
||||
* Any real docu ?
|
||||
* Translate a logical disk identifier (LDID) into its string representation
|
||||
*/
|
||||
BOOL SETUPX_TranslateLDID(int ldid, LPSTR buffer, WORD buflen)
|
||||
{
|
||||
BOOL handled = FALSE;
|
||||
|
||||
if ((ldid >= LDID_SRCPATH) && (ldid <= LDID_OLD_WIN))
|
||||
{
|
||||
if (LDID_Data[ldid].RegValName)
|
||||
{
|
||||
HKEY hKey;
|
||||
|
||||
if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD type, len = buflen;
|
||||
|
||||
if ( (RegQueryValueExA(hKey, LDID_Data[ldid].RegValName,
|
||||
NULL, &type, buffer, &len) == ERROR_SUCCESS)
|
||||
&& (type == REG_SZ) )
|
||||
{
|
||||
TRACE("found value '%s' for LDID %d\n", buffer, ldid);
|
||||
handled = TRUE;
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!handled)
|
||||
{
|
||||
switch(ldid)
|
||||
{
|
||||
case LDID_SRCPATH:
|
||||
FIXME("LDID_SRCPATH: what exactly do we have to do here ?\n");
|
||||
break;
|
||||
case LDID_SYS:
|
||||
GetSystemDirectoryA(buffer, buflen);
|
||||
handled = TRUE;
|
||||
break;
|
||||
case LDID_APPS:
|
||||
case LDID_MACHINE:
|
||||
case LDID_HOST_WINBOOT:
|
||||
case LDID_BOOT:
|
||||
case LDID_BOOT_HOST:
|
||||
strncpy(buffer, "C:\\", buflen);
|
||||
buffer[buflen-1] = '\0';
|
||||
handled = TRUE;
|
||||
break;
|
||||
case 49001: /* what's this ???
|
||||
does this have to pop up a dialog or what ? */
|
||||
strncpy(buffer, "C:\\Program Files", buflen);
|
||||
buffer[buflen-1] = '\0';
|
||||
FIXME("what is LDID 49001 ?? returning %s for now.\n", buffer);
|
||||
handled = TRUE;
|
||||
break;
|
||||
default:
|
||||
if (LDID_Data[ldid].StdString)
|
||||
{
|
||||
UINT len = GetWindowsDirectoryA(buffer, buflen);
|
||||
if (len <= buflen-1)
|
||||
{
|
||||
buffer += len;
|
||||
buflen -= len;
|
||||
*buffer++ = '\\';
|
||||
buflen--;
|
||||
strncpy(buffer, LDID_Data[ldid].StdString, buflen);
|
||||
buffer[buflen-1] = '\0';
|
||||
}
|
||||
handled = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
FIXME("unimplemented LDID %d\n", ldid);
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
/*
|
||||
* GenFormStrWithoutPlaceHolders
|
||||
*/
|
||||
void WINAPI GenFormStrWithoutPlaceHolders16( LPSTR szDst, LPCSTR szSrc, HINF16 hInf)
|
||||
{
|
||||
FIXME("(%p, '%s', %04x), stub.\n", szDst, szSrc, hInf);
|
||||
strcpy(szDst, szSrc);
|
||||
LPCSTR pSrc = szSrc, pSrcEnd = szSrc + strlen(szSrc);
|
||||
LPSTR pDst = szDst, p, pPHBegin;
|
||||
int count;
|
||||
|
||||
FIXME("(%p, '%s', %04x), semi stub.\n", szDst, szSrc, hInf);
|
||||
while (pSrc < pSrcEnd)
|
||||
{
|
||||
p = strchr(pSrc, '%');
|
||||
if (p)
|
||||
{
|
||||
count = (int)p - (int)pSrc;
|
||||
strncpy(pDst, pSrc, count);
|
||||
pSrc += count;
|
||||
pDst += count;
|
||||
pPHBegin = p+1;
|
||||
p = strchr(pPHBegin, '%');
|
||||
if (p)
|
||||
{
|
||||
char placeholder[80]; /* that really ought to be enough ;) */
|
||||
int ldid;
|
||||
BOOL done = TRUE;
|
||||
count = (int)p - (int)pPHBegin;
|
||||
strncpy(placeholder, pPHBegin, count);
|
||||
placeholder[count] = '\0';
|
||||
ldid = atoi(placeholder);
|
||||
if (ldid)
|
||||
{
|
||||
done = SETUPX_TranslateLDID(ldid, pDst, 256);
|
||||
if (done)
|
||||
pDst += strlen(pDst);
|
||||
}
|
||||
else
|
||||
{ /* hmm, string placeholder. Need to look up
|
||||
in the [strings] section of the hInf */
|
||||
DWORD ret;
|
||||
char buf[256]; /* long enough ? */
|
||||
|
||||
ret = GetPrivateProfileStringA("strings", placeholder, "",
|
||||
buf, 256, IP_GetFileName(hInf));
|
||||
if (ret)
|
||||
{
|
||||
strcpy(pDst, buf);
|
||||
pDst += strlen(buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("placeholder string '%s' not found !\n", placeholder);
|
||||
done = FALSE;
|
||||
}
|
||||
}
|
||||
if (!done)
|
||||
{ /* copy raw placeholder string over */
|
||||
count = (int)p - (int)pPHBegin + 2;
|
||||
strncpy(pDst, pPHBegin-1, count);
|
||||
pDst += count;
|
||||
|
||||
}
|
||||
pSrc = p+1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* copy the remaining source string over */
|
||||
strncpy(pDst, pSrc, (int)pSrcEnd - (int)pSrc + 1);
|
||||
break;
|
||||
}
|
||||
TRACE("ret '%s'\n", szDst);
|
||||
}
|
||||
|
||||
RETERR16 WINAPI CtlGetLddPath16(LOGDISKID16 ldid, LPSTR szPath)
|
||||
|
|
Loading…
Reference in New Issue