mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 09:31:44 +00:00
Autosyncing with Wine HEAD
svn path=/trunk/; revision=24196
This commit is contained in:
parent
a11691c3c4
commit
04b927e3ff
13 changed files with 363 additions and 245 deletions
|
@ -3860,229 +3860,6 @@ static UINT ACTION_ExecuteAction(MSIPACKAGE *package)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Code based off of code located here
|
||||
* http://www.codeproject.com/gdi/fontnamefromfile.asp
|
||||
*
|
||||
* Using string index 4 (full font name) instead of 1 (family name)
|
||||
*/
|
||||
static LPWSTR load_ttfname_from(LPCWSTR filename)
|
||||
{
|
||||
HANDLE handle;
|
||||
LPWSTR ret = NULL;
|
||||
int i;
|
||||
|
||||
typedef struct _tagTT_OFFSET_TABLE{
|
||||
USHORT uMajorVersion;
|
||||
USHORT uMinorVersion;
|
||||
USHORT uNumOfTables;
|
||||
USHORT uSearchRange;
|
||||
USHORT uEntrySelector;
|
||||
USHORT uRangeShift;
|
||||
}TT_OFFSET_TABLE;
|
||||
|
||||
typedef struct _tagTT_TABLE_DIRECTORY{
|
||||
char szTag[4]; /* table name */
|
||||
ULONG uCheckSum; /* Check sum */
|
||||
ULONG uOffset; /* Offset from beginning of file */
|
||||
ULONG uLength; /* length of the table in bytes */
|
||||
}TT_TABLE_DIRECTORY;
|
||||
|
||||
typedef struct _tagTT_NAME_TABLE_HEADER{
|
||||
USHORT uFSelector; /* format selector. Always 0 */
|
||||
USHORT uNRCount; /* Name Records count */
|
||||
USHORT uStorageOffset; /* Offset for strings storage,
|
||||
* from start of the table */
|
||||
}TT_NAME_TABLE_HEADER;
|
||||
|
||||
typedef struct _tagTT_NAME_RECORD{
|
||||
USHORT uPlatformID;
|
||||
USHORT uEncodingID;
|
||||
USHORT uLanguageID;
|
||||
USHORT uNameID;
|
||||
USHORT uStringLength;
|
||||
USHORT uStringOffset; /* from start of storage area */
|
||||
}TT_NAME_RECORD;
|
||||
|
||||
#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
|
||||
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
|
||||
|
||||
handle = CreateFileW(filename ,GENERIC_READ, 0, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, 0 );
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
TT_TABLE_DIRECTORY tblDir;
|
||||
BOOL bFound = FALSE;
|
||||
TT_OFFSET_TABLE ttOffsetTable;
|
||||
DWORD dwRead;
|
||||
|
||||
ReadFile(handle,&ttOffsetTable, sizeof(TT_OFFSET_TABLE),&dwRead,NULL);
|
||||
ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);
|
||||
ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);
|
||||
ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);
|
||||
|
||||
if (ttOffsetTable.uMajorVersion != 1 ||
|
||||
ttOffsetTable.uMinorVersion != 0)
|
||||
return NULL;
|
||||
|
||||
for (i=0; i< ttOffsetTable.uNumOfTables; i++)
|
||||
{
|
||||
ReadFile(handle,&tblDir, sizeof(TT_TABLE_DIRECTORY),&dwRead,NULL);
|
||||
if (strncmp(tblDir.szTag,"name",4)==0)
|
||||
{
|
||||
bFound = TRUE;
|
||||
tblDir.uLength = SWAPLONG(tblDir.uLength);
|
||||
tblDir.uOffset = SWAPLONG(tblDir.uOffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bFound)
|
||||
{
|
||||
TT_NAME_TABLE_HEADER ttNTHeader;
|
||||
TT_NAME_RECORD ttRecord;
|
||||
|
||||
SetFilePointer(handle, tblDir.uOffset, NULL, FILE_BEGIN);
|
||||
ReadFile(handle,&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER),
|
||||
&dwRead,NULL);
|
||||
|
||||
ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
|
||||
ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
|
||||
bFound = FALSE;
|
||||
for(i=0; i<ttNTHeader.uNRCount; i++)
|
||||
{
|
||||
ReadFile(handle,&ttRecord, sizeof(TT_NAME_RECORD),&dwRead,NULL);
|
||||
ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
|
||||
/* 4 is the Full Font Name */
|
||||
if(ttRecord.uNameID == 4)
|
||||
{
|
||||
int nPos;
|
||||
LPSTR buf;
|
||||
static LPCSTR tt = " (TrueType)";
|
||||
|
||||
ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
|
||||
ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
|
||||
nPos = SetFilePointer(handle, 0, NULL, FILE_CURRENT);
|
||||
SetFilePointer(handle, tblDir.uOffset +
|
||||
ttRecord.uStringOffset +
|
||||
ttNTHeader.uStorageOffset,
|
||||
NULL, FILE_BEGIN);
|
||||
buf = msi_alloc_zero( ttRecord.uStringLength + 1 + strlen(tt) );
|
||||
ReadFile(handle, buf, ttRecord.uStringLength, &dwRead, NULL);
|
||||
if (strlen(buf) > 0)
|
||||
{
|
||||
strcat(buf,tt);
|
||||
ret = strdupAtoW(buf);
|
||||
msi_free(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
msi_free(buf);
|
||||
SetFilePointer(handle,nPos, NULL, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(handle);
|
||||
}
|
||||
else
|
||||
ERR("Unable to open font file %s\n", debugstr_w(filename));
|
||||
|
||||
TRACE("Returning fontname %s\n",debugstr_w(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
|
||||
{
|
||||
MSIPACKAGE *package = (MSIPACKAGE*)param;
|
||||
LPWSTR name;
|
||||
LPCWSTR filename;
|
||||
MSIFILE *file;
|
||||
static const WCHAR regfont1[] =
|
||||
{'S','o','f','t','w','a','r','e','\\',
|
||||
'M','i','c','r','o','s','o','f','t','\\',
|
||||
'W','i','n','d','o','w','s',' ','N','T','\\',
|
||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||
'F','o','n','t','s',0};
|
||||
static const WCHAR regfont2[] =
|
||||
{'S','o','f','t','w','a','r','e','\\',
|
||||
'M','i','c','r','o','s','o','f','t','\\',
|
||||
'W','i','n','d','o','w','s','\\',
|
||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||
'F','o','n','t','s',0};
|
||||
HKEY hkey1;
|
||||
HKEY hkey2;
|
||||
MSIRECORD *uirow;
|
||||
LPWSTR uipath, p;
|
||||
|
||||
filename = MSI_RecordGetString( row, 1 );
|
||||
file = get_loaded_file( package, filename );
|
||||
if (!file)
|
||||
{
|
||||
ERR("Unable to load file\n");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/* check to make sure that component is installed */
|
||||
if (!ACTION_VerifyComponentForAction( file->Component, INSTALLSTATE_LOCAL))
|
||||
{
|
||||
TRACE("Skipping: Component not scheduled for install\n");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont1,&hkey1);
|
||||
RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2);
|
||||
|
||||
if (MSI_RecordIsNull(row,2))
|
||||
name = load_ttfname_from( file->TargetPath );
|
||||
else
|
||||
name = msi_dup_record_field(row,2);
|
||||
|
||||
if (name)
|
||||
{
|
||||
msi_reg_set_val_str( hkey1, name, file->FileName );
|
||||
msi_reg_set_val_str( hkey2, name, file->FileName );
|
||||
}
|
||||
|
||||
msi_free(name);
|
||||
RegCloseKey(hkey1);
|
||||
RegCloseKey(hkey2);
|
||||
|
||||
/* the UI chunk */
|
||||
uirow = MSI_CreateRecord( 1 );
|
||||
uipath = strdupW( file->TargetPath );
|
||||
p = strrchrW(uipath,'\\');
|
||||
if (p) p++;
|
||||
else p = uipath;
|
||||
MSI_RecordSetStringW( uirow, 1, p );
|
||||
ui_actiondata( package, szRegisterFonts, uirow);
|
||||
msiobj_release( &uirow->hdr );
|
||||
msi_free( uipath );
|
||||
/* FIXME: call ui_progress? */
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ACTION_RegisterFonts(MSIPACKAGE *package)
|
||||
{
|
||||
UINT rc;
|
||||
MSIQUERY * view;
|
||||
static const WCHAR ExecSeqQuery[] =
|
||||
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
'`','F','o','n','t','`',0};
|
||||
|
||||
rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
TRACE("MSI_DatabaseOpenViewW failed: %d\n", rc);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
MSI_IterateRecords(view, NULL, ITERATE_RegisterFonts, package);
|
||||
msiobj_release(&view->hdr);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param)
|
||||
{
|
||||
MSIPACKAGE *package = (MSIPACKAGE*)param;
|
||||
|
|
|
@ -253,6 +253,7 @@ extern UINT ACTION_RegisterClassInfo(MSIPACKAGE *package);
|
|||
extern UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package);
|
||||
extern UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package);
|
||||
extern UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package);
|
||||
extern UINT ACTION_RegisterFonts(MSIPACKAGE *package);
|
||||
|
||||
|
||||
/* Helpers */
|
||||
|
|
|
@ -845,6 +845,11 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
|||
|
||||
RegCreateKeyW( hkey2, cls->Context, &hkey3 );
|
||||
file = get_loaded_file( package, comp->KeyPath );
|
||||
if (!file)
|
||||
{
|
||||
TRACE("COM server not provided, skipping class %s\n", debugstr_w(cls->clsid));
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: Implement install on demand (advertised components).
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#define YYLEX_PARAM info
|
||||
#define YYPARSE_PARAM info
|
||||
|
||||
static int COND_error(const char *str);
|
||||
static int cond_error(const char *str);
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
||||
|
||||
|
@ -59,7 +59,7 @@ struct cond_str {
|
|||
|
||||
static LPWSTR COND_GetString( struct cond_str *str );
|
||||
static LPWSTR COND_GetLiteral( struct cond_str *str );
|
||||
static int COND_lex( void *COND_lval, COND_input *info);
|
||||
static int cond_lex( void *COND_lval, COND_input *info);
|
||||
static const WCHAR szEmpty[] = { 0 };
|
||||
|
||||
static INT compare_int( INT a, INT operator, INT b );
|
||||
|
@ -667,7 +667,7 @@ static int COND_GetOne( struct cond_str *str, COND_input *cond )
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int COND_lex( void *COND_lval, COND_input *cond )
|
||||
static int cond_lex( void *COND_lval, COND_input *cond )
|
||||
{
|
||||
int rc;
|
||||
struct cond_str *str = COND_lval;
|
||||
|
@ -707,7 +707,7 @@ static LPWSTR COND_GetLiteral( struct cond_str *str )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int COND_error(const char *str)
|
||||
static int cond_error(const char *str)
|
||||
{
|
||||
TRACE("%s\n", str );
|
||||
return 0;
|
||||
|
@ -728,7 +728,7 @@ MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition )
|
|||
cond.n = 0;
|
||||
cond.result = MSICONDITION_ERROR;
|
||||
|
||||
if ( !COND_parse( &cond ) )
|
||||
if ( !cond_parse( &cond ) )
|
||||
r = cond.result;
|
||||
else
|
||||
r = MSICONDITION_ERROR;
|
||||
|
|
|
@ -64,6 +64,11 @@ static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
|
|||
r = IStorage_Release( db->storage );
|
||||
if( r )
|
||||
ERR("database reference count was not zero (%ld)\n", r);
|
||||
if (db->deletefile)
|
||||
{
|
||||
DeleteFileW( db->deletefile );
|
||||
msi_free( db->deletefile );
|
||||
}
|
||||
}
|
||||
|
||||
UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
|
||||
|
@ -74,6 +79,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
|
|||
UINT ret = ERROR_FUNCTION_FAILED;
|
||||
LPCWSTR szMode;
|
||||
STATSTG stat;
|
||||
BOOL created = FALSE;
|
||||
|
||||
TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) );
|
||||
|
||||
|
@ -83,12 +89,15 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
|
|||
szMode = szPersist;
|
||||
if( HIWORD( szPersist ) )
|
||||
{
|
||||
/* UINT len = lstrlenW( szPerist ) + 1; */
|
||||
FIXME("don't support persist files yet\b");
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
/* szMode = msi_alloc( len * sizeof (DWORD) ); */
|
||||
if (!CopyFileW( szDBPath, szPersist, FALSE ))
|
||||
return ERROR_OPEN_FAILED;
|
||||
|
||||
szDBPath = szPersist;
|
||||
szPersist = MSIDBOPEN_TRANSACT;
|
||||
created = TRUE;
|
||||
}
|
||||
else if( szPersist == MSIDBOPEN_READONLY )
|
||||
|
||||
if( szPersist == MSIDBOPEN_READONLY )
|
||||
{
|
||||
r = StgOpenStorage( szDBPath, NULL,
|
||||
STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
|
||||
|
@ -97,13 +106,14 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
|
|||
{
|
||||
/* FIXME: MSIDBOPEN_CREATE should case STGM_TRANSACTED flag to be
|
||||
* used here: */
|
||||
r = StgCreateDocfile( szDBPath,
|
||||
STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
|
||||
r = StgCreateDocfile( szDBPath,
|
||||
STGM_CREATE|STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
|
||||
if( r == ERROR_SUCCESS )
|
||||
{
|
||||
IStorage_SetClass( stg, &CLSID_MsiDatabase );
|
||||
r = init_string_table( stg );
|
||||
}
|
||||
created = TRUE;
|
||||
}
|
||||
else if( szPersist == MSIDBOPEN_TRANSACT )
|
||||
{
|
||||
|
@ -157,6 +167,10 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
|
|||
|
||||
db->storage = stg;
|
||||
db->mode = szMode;
|
||||
if (created)
|
||||
db->deletefile = strdupW( szDBPath );
|
||||
else
|
||||
db->deletefile = NULL;
|
||||
list_init( &db->tables );
|
||||
list_init( &db->transforms );
|
||||
|
||||
|
|
|
@ -2328,6 +2328,38 @@ static void msi_dialog_vcl_add_columns( msi_dialog *dialog, msi_control *control
|
|||
}
|
||||
}
|
||||
|
||||
static void msi_dialog_vcl_add_drives( msi_dialog *dialog, msi_control *control )
|
||||
{
|
||||
LPWSTR drives, ptr;
|
||||
LVITEMW lvitem;
|
||||
DWORD size;
|
||||
int i = 0;
|
||||
|
||||
size = GetLogicalDriveStringsW( 0, NULL );
|
||||
if ( !size ) return;
|
||||
|
||||
drives = msi_alloc( (size + 1) * sizeof(WCHAR) );
|
||||
if ( !drives ) return;
|
||||
|
||||
GetLogicalDriveStringsW( size, drives );
|
||||
|
||||
ptr = drives;
|
||||
while (*ptr)
|
||||
{
|
||||
lvitem.mask = LVIF_TEXT;
|
||||
lvitem.iItem = i;
|
||||
lvitem.iSubItem = 0;
|
||||
lvitem.pszText = ptr;
|
||||
lvitem.cchTextMax = lstrlenW(ptr) + 1;
|
||||
SendMessageW( control->hwnd, LVM_INSERTITEMW, 0, (LPARAM)&lvitem );
|
||||
|
||||
ptr += lstrlenW(ptr) + 1;
|
||||
i++;
|
||||
}
|
||||
|
||||
msi_free( drives );
|
||||
}
|
||||
|
||||
static UINT msi_dialog_volumecost_list( msi_dialog *dialog, MSIRECORD *rec )
|
||||
{
|
||||
msi_control *control;
|
||||
|
@ -2341,6 +2373,7 @@ static UINT msi_dialog_volumecost_list( msi_dialog *dialog, MSIRECORD *rec )
|
|||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
msi_dialog_vcl_add_columns( dialog, control, rec );
|
||||
msi_dialog_vcl_add_drives( dialog, control );
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
|
262
reactos/dll/win32/msi/font.c
Normal file
262
reactos/dll/win32/msi/font.c
Normal file
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* Implementation of the Microsoft Installer (msi.dll)
|
||||
*
|
||||
* Copyright 2004,2005 Aric Stewart 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
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
#include "wine/debug.h"
|
||||
#include "msipriv.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "action.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
||||
|
||||
typedef struct _tagTT_OFFSET_TABLE {
|
||||
USHORT uMajorVersion;
|
||||
USHORT uMinorVersion;
|
||||
USHORT uNumOfTables;
|
||||
USHORT uSearchRange;
|
||||
USHORT uEntrySelector;
|
||||
USHORT uRangeShift;
|
||||
} TT_OFFSET_TABLE;
|
||||
|
||||
typedef struct _tagTT_TABLE_DIRECTORY {
|
||||
char szTag[4]; /* table name */
|
||||
ULONG uCheckSum; /* Check sum */
|
||||
ULONG uOffset; /* Offset from beginning of file */
|
||||
ULONG uLength; /* length of the table in bytes */
|
||||
} TT_TABLE_DIRECTORY;
|
||||
|
||||
typedef struct _tagTT_NAME_TABLE_HEADER {
|
||||
USHORT uFSelector; /* format selector. Always 0 */
|
||||
USHORT uNRCount; /* Name Records count */
|
||||
USHORT uStorageOffset; /* Offset for strings storage,
|
||||
* from start of the table */
|
||||
} TT_NAME_TABLE_HEADER;
|
||||
|
||||
typedef struct _tagTT_NAME_RECORD {
|
||||
USHORT uPlatformID;
|
||||
USHORT uEncodingID;
|
||||
USHORT uLanguageID;
|
||||
USHORT uNameID;
|
||||
USHORT uStringLength;
|
||||
USHORT uStringOffset; /* from start of storage area */
|
||||
} TT_NAME_RECORD;
|
||||
|
||||
#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
|
||||
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
|
||||
|
||||
static const WCHAR szRegisterFonts[] =
|
||||
{'R','e','g','i','s','t','e','r','F','o','n','t','s',0};
|
||||
|
||||
/*
|
||||
* Code based off of code located here
|
||||
* http://www.codeproject.com/gdi/fontnamefromfile.asp
|
||||
*
|
||||
* Using string index 4 (full font name) instead of 1 (family name)
|
||||
*/
|
||||
static LPWSTR load_ttfname_from(LPCWSTR filename)
|
||||
{
|
||||
TT_TABLE_DIRECTORY tblDir;
|
||||
BOOL bFound = FALSE;
|
||||
TT_OFFSET_TABLE ttOffsetTable;
|
||||
TT_NAME_TABLE_HEADER ttNTHeader;
|
||||
TT_NAME_RECORD ttRecord;
|
||||
DWORD dwRead;
|
||||
HANDLE handle;
|
||||
LPWSTR ret = NULL;
|
||||
int i;
|
||||
|
||||
handle = CreateFileW(filename ,GENERIC_READ, 0, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, 0 );
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ERR("Unable to open font file %s\n", debugstr_w(filename));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ReadFile(handle,&ttOffsetTable, sizeof(TT_OFFSET_TABLE),&dwRead,NULL))
|
||||
goto end;
|
||||
|
||||
ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);
|
||||
ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);
|
||||
ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);
|
||||
|
||||
if (ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0)
|
||||
goto end;
|
||||
|
||||
for (i=0; i< ttOffsetTable.uNumOfTables; i++)
|
||||
{
|
||||
if (!ReadFile(handle,&tblDir, sizeof(TT_TABLE_DIRECTORY),&dwRead,NULL))
|
||||
break;
|
||||
if (memcmp(tblDir.szTag,"name",4)==0)
|
||||
{
|
||||
bFound = TRUE;
|
||||
tblDir.uLength = SWAPLONG(tblDir.uLength);
|
||||
tblDir.uOffset = SWAPLONG(tblDir.uOffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
goto end;
|
||||
|
||||
SetFilePointer(handle, tblDir.uOffset, NULL, FILE_BEGIN);
|
||||
if (!ReadFile(handle,&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER), &dwRead,NULL))
|
||||
goto end;
|
||||
|
||||
ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
|
||||
ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
|
||||
bFound = FALSE;
|
||||
for(i=0; i<ttNTHeader.uNRCount; i++)
|
||||
{
|
||||
if (!ReadFile(handle,&ttRecord, sizeof(TT_NAME_RECORD),&dwRead,NULL))
|
||||
break;
|
||||
|
||||
ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
|
||||
/* 4 is the Full Font Name */
|
||||
if(ttRecord.uNameID == 4)
|
||||
{
|
||||
int nPos;
|
||||
LPSTR buf;
|
||||
static LPCSTR tt = " (TrueType)";
|
||||
|
||||
ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
|
||||
ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
|
||||
nPos = SetFilePointer(handle, 0, NULL, FILE_CURRENT);
|
||||
SetFilePointer(handle, tblDir.uOffset +
|
||||
ttRecord.uStringOffset +
|
||||
ttNTHeader.uStorageOffset,
|
||||
NULL, FILE_BEGIN);
|
||||
buf = msi_alloc_zero( ttRecord.uStringLength + 1 + strlen(tt) );
|
||||
ReadFile(handle, buf, ttRecord.uStringLength, &dwRead, NULL);
|
||||
if (strlen(buf) > 0)
|
||||
{
|
||||
strcat(buf,tt);
|
||||
ret = strdupAtoW(buf);
|
||||
msi_free(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
msi_free(buf);
|
||||
SetFilePointer(handle,nPos, NULL, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
CloseHandle(handle);
|
||||
|
||||
TRACE("Returning fontname %s\n",debugstr_w(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
|
||||
{
|
||||
MSIPACKAGE *package = (MSIPACKAGE*)param;
|
||||
LPWSTR name;
|
||||
LPCWSTR filename;
|
||||
MSIFILE *file;
|
||||
static const WCHAR regfont1[] =
|
||||
{'S','o','f','t','w','a','r','e','\\',
|
||||
'M','i','c','r','o','s','o','f','t','\\',
|
||||
'W','i','n','d','o','w','s',' ','N','T','\\',
|
||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||
'F','o','n','t','s',0};
|
||||
static const WCHAR regfont2[] =
|
||||
{'S','o','f','t','w','a','r','e','\\',
|
||||
'M','i','c','r','o','s','o','f','t','\\',
|
||||
'W','i','n','d','o','w','s','\\',
|
||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||
'F','o','n','t','s',0};
|
||||
HKEY hkey1;
|
||||
HKEY hkey2;
|
||||
MSIRECORD *uirow;
|
||||
LPWSTR uipath, p;
|
||||
|
||||
filename = MSI_RecordGetString( row, 1 );
|
||||
file = get_loaded_file( package, filename );
|
||||
if (!file)
|
||||
{
|
||||
ERR("Unable to load file\n");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/* check to make sure that component is installed */
|
||||
if (!ACTION_VerifyComponentForAction( file->Component, INSTALLSTATE_LOCAL))
|
||||
{
|
||||
TRACE("Skipping: Component not scheduled for install\n");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont1,&hkey1);
|
||||
RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2);
|
||||
|
||||
if (MSI_RecordIsNull(row,2))
|
||||
name = load_ttfname_from( file->TargetPath );
|
||||
else
|
||||
name = msi_dup_record_field(row,2);
|
||||
|
||||
if (name)
|
||||
{
|
||||
msi_reg_set_val_str( hkey1, name, file->FileName );
|
||||
msi_reg_set_val_str( hkey2, name, file->FileName );
|
||||
}
|
||||
|
||||
msi_free(name);
|
||||
RegCloseKey(hkey1);
|
||||
RegCloseKey(hkey2);
|
||||
|
||||
/* the UI chunk */
|
||||
uirow = MSI_CreateRecord( 1 );
|
||||
uipath = strdupW( file->TargetPath );
|
||||
p = strrchrW(uipath,'\\');
|
||||
if (p) p++;
|
||||
else p = uipath;
|
||||
MSI_RecordSetStringW( uirow, 1, p );
|
||||
ui_actiondata( package, szRegisterFonts, uirow);
|
||||
msiobj_release( &uirow->hdr );
|
||||
msi_free( uipath );
|
||||
/* FIXME: call ui_progress? */
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT ACTION_RegisterFonts(MSIPACKAGE *package)
|
||||
{
|
||||
UINT rc;
|
||||
MSIQUERY * view;
|
||||
static const WCHAR ExecSeqQuery[] =
|
||||
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
'`','F','o','n','t','`',0};
|
||||
|
||||
rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
TRACE("MSI_DatabaseOpenViewW failed: %d\n", rc);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
MSI_IterateRecords(view, NULL, ITERATE_RegisterFonts, package);
|
||||
msiobj_release(&view->hdr);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
|
@ -38,6 +38,7 @@
|
|||
<file>distinct.c</file>
|
||||
<file>events.c</file>
|
||||
<file>files.c</file>
|
||||
<file>font.c</file>
|
||||
<file>format.c</file>
|
||||
<file>handle.c</file>
|
||||
<file>helpers.c</file>
|
||||
|
|
|
@ -71,6 +71,7 @@ typedef struct tagMSIDATABASE
|
|||
MSIOBJECTHDR hdr;
|
||||
IStorage *storage;
|
||||
string_table *strings;
|
||||
LPWSTR deletefile;
|
||||
LPCWSTR mode;
|
||||
struct list tables;
|
||||
struct list transforms;
|
||||
|
@ -337,6 +338,7 @@ extern UINT msi_string_get_codepage( string_table *st );
|
|||
|
||||
|
||||
extern BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name );
|
||||
extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table );
|
||||
|
||||
extern UINT read_raw_stream_data( MSIDATABASE*, LPCWSTR stname,
|
||||
USHORT **pdata, UINT *psz );
|
||||
|
|
|
@ -754,6 +754,12 @@ UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb )
|
|||
|
||||
msiobj_release( &db->hdr );
|
||||
|
||||
if (r == ERROR_SUCCESS)
|
||||
{
|
||||
msi_free( db->deletefile );
|
||||
db->deletefile = NULL;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -893,6 +899,18 @@ MSICONDITION WINAPI MsiDatabaseIsTablePersistentA(
|
|||
MSICONDITION WINAPI MsiDatabaseIsTablePersistentW(
|
||||
MSIHANDLE hDatabase, LPCWSTR szTableName)
|
||||
{
|
||||
FIXME("%lx %s\n", hDatabase, debugstr_w(szTableName));
|
||||
return MSICONDITION_FALSE;
|
||||
MSIDATABASE *db;
|
||||
MSICONDITION r;
|
||||
|
||||
TRACE("%lx %s\n", hDatabase, debugstr_w(szTableName));
|
||||
|
||||
db = msihandle2msiinfo( hDatabase, MSIHANDLETYPE_DATABASE );
|
||||
if( !db )
|
||||
return MSICONDITION_ERROR;
|
||||
|
||||
r = MSI_DatabaseIsTablePersistent( db, szTableName );
|
||||
|
||||
msiobj_release( &db->hdr );
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#define YYLEX_PARAM info
|
||||
#define YYPARSE_PARAM info
|
||||
|
||||
extern int SQL_error(const char *str);
|
||||
static int sql_error(const char *str);
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
||||
|
||||
|
@ -51,7 +51,7 @@ typedef struct tag_SQL_input
|
|||
|
||||
static LPWSTR SQL_getstring( void *info, struct sql_str *str );
|
||||
static INT SQL_getint( void *info );
|
||||
static int SQL_lex( void *SQL_lval, SQL_input *info );
|
||||
static int sql_lex( void *SQL_lval, SQL_input *info );
|
||||
|
||||
static void *parser_alloc( void *info, unsigned int sz );
|
||||
static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column );
|
||||
|
@ -686,7 +686,7 @@ static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR colu
|
|||
return col;
|
||||
}
|
||||
|
||||
int SQL_lex( void *SQL_lval, SQL_input *sql )
|
||||
static int sql_lex( void *SQL_lval, SQL_input *sql )
|
||||
{
|
||||
int token;
|
||||
struct sql_str * str = SQL_lval;
|
||||
|
@ -752,7 +752,7 @@ INT SQL_getint( void *info )
|
|||
return r;
|
||||
}
|
||||
|
||||
int SQL_error( const char *str )
|
||||
static int sql_error( const char *str )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -851,7 +851,7 @@ UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview,
|
|||
sql.view = phview;
|
||||
sql.mem = mem;
|
||||
|
||||
r = SQL_parse(&sql);
|
||||
r = sql_parse(&sql);
|
||||
|
||||
TRACE("Parse returned %d\n", r);
|
||||
if( r )
|
||||
|
|
|
@ -1643,6 +1643,14 @@ UINT MSI_CommitTables( MSIDATABASE *db )
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table )
|
||||
{
|
||||
if (!table)
|
||||
return MSICONDITION_ERROR;
|
||||
|
||||
return MSICONDITION_FALSE;
|
||||
}
|
||||
|
||||
static MSIRECORD *msi_get_transform_record( MSITABLEVIEW *tv, string_table *st, USHORT *rawdata )
|
||||
{
|
||||
UINT i, val, ofs = 0;
|
||||
|
|
|
@ -22,13 +22,10 @@
|
|||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "query.h"
|
||||
#include "sql.tab.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
||||
|
||||
/*
|
||||
** All the keywords of the SQL language are stored as in a hash
|
||||
** table composed of instances of the following structure.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue