ReactOS 0.4.15-dev-7953-g1f49173
font.c
Go to the documentation of this file.
1/*
2 * Implementation of the Microsoft Installer (msi.dll)
3 *
4 * Copyright 2004,2005 Aric Stewart for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdarg.h>
22#include "windef.h"
23#include "winbase.h"
24#include "winerror.h"
25#include "winreg.h"
26#include "wine/debug.h"
27#include "msipriv.h"
28
30
31typedef struct _tagTT_OFFSET_TABLE {
39
40typedef struct _tagTT_TABLE_DIRECTORY {
41 char szTag[4]; /* table name */
42 ULONG uCheckSum; /* Check sum */
43 ULONG uOffset; /* Offset from beginning of file */
44 ULONG uLength; /* length of the table in bytes */
46
48 USHORT uFSelector; /* format selector. Always 0 */
49 USHORT uNRCount; /* Name Records count */
50 USHORT uStorageOffset; /* Offset for strings storage,
51 * from start of the table */
53
54#define NAME_ID_FULL_FONT_NAME 4
55#define NAME_ID_VERSION 5
56
57typedef struct _tagTT_NAME_RECORD {
63 USHORT uStringOffset; /* from start of storage area */
65
66#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
67#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
68
69/*
70 * Code based off of code located here
71 * http://www.codeproject.com/gdi/fontnamefromfile.asp
72 */
73static WCHAR *load_ttf_name_id( MSIPACKAGE *package, const WCHAR *filename, DWORD id )
74{
75 TT_TABLE_DIRECTORY tblDir;
76 BOOL bFound = FALSE;
77 TT_OFFSET_TABLE ttOffsetTable;
78 TT_NAME_TABLE_HEADER ttNTHeader;
79 TT_NAME_RECORD ttRecord;
80 DWORD dwRead;
82 LPWSTR ret = NULL;
83 int i;
84
85 if (package)
87 else
90 {
91 ERR("Unable to open font file %s\n", debugstr_w(filename));
92 return NULL;
93 }
94
95 if (!ReadFile(handle,&ttOffsetTable, sizeof(TT_OFFSET_TABLE),&dwRead,NULL))
96 goto end;
97
98 ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);
99 ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);
100 ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);
101
102 if ((ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0) &&
103 (ttOffsetTable.uMajorVersion != 0x4f54 || ttOffsetTable.uMinorVersion != 0x544f))
104 goto end;
105
106 for (i=0; i< ttOffsetTable.uNumOfTables; i++)
107 {
108 if (!ReadFile(handle,&tblDir, sizeof(TT_TABLE_DIRECTORY),&dwRead,NULL))
109 break;
110 if (memcmp(tblDir.szTag,"name",4)==0)
111 {
112 bFound = TRUE;
113 tblDir.uLength = SWAPLONG(tblDir.uLength);
114 tblDir.uOffset = SWAPLONG(tblDir.uOffset);
115 break;
116 }
117 }
118
119 if (!bFound)
120 goto end;
121
123 if (!ReadFile(handle,&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER), &dwRead,NULL))
124 goto end;
125
126 ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
127 ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
128 for(i=0; i<ttNTHeader.uNRCount; i++)
129 {
130 if (!ReadFile(handle,&ttRecord, sizeof(TT_NAME_RECORD),&dwRead,NULL))
131 break;
132
133 ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
134 ttRecord.uPlatformID = SWAPWORD(ttRecord.uPlatformID);
135 ttRecord.uEncodingID = SWAPWORD(ttRecord.uEncodingID);
136 if (ttRecord.uNameID == id && ttRecord.uPlatformID == 3 &&
137 (ttRecord.uEncodingID == 0 || ttRecord.uEncodingID == 1))
138 {
139 WCHAR *buf;
140 unsigned int i;
141
142 ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
143 ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
144 SetFilePointer(handle, tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset,
146 if (!(buf = msi_alloc_zero( ttRecord.uStringLength + sizeof(WCHAR) ))) goto end;
147 dwRead = 0;
148 ReadFile(handle, buf, ttRecord.uStringLength, &dwRead, NULL);
149 if (dwRead % sizeof(WCHAR))
150 {
151 msi_free(buf);
152 goto end;
153 }
154 for (i = 0; i < dwRead / sizeof(WCHAR); i++) buf[i] = SWAPWORD(buf[i]);
155 ret = strdupW(buf);
156 msi_free(buf);
157 break;
158 }
159 }
160
161end:
163 return ret;
164}
165
167{
168 WCHAR *name, *ret = NULL;
169
171 {
172 if (!name[0])
173 {
174 WARN("empty font name\n");
175 msi_free( name );
176 return NULL;
177 }
178 ret = msi_alloc( (lstrlenW( name ) + lstrlenW( L" (TrueType)" ) + 1 ) * sizeof(WCHAR) );
179 lstrcpyW( ret, name );
180 lstrcatW( ret, L" (TrueType)" );
181 msi_free( name );
182 }
183 return ret;
184}
185
187{
188 WCHAR *version, *p, *q, *ret = NULL;
189
191 {
192 int len, major = 0, minor = 0;
193 if ((p = wcschr( version, ';' ))) *p = 0;
194 p = version;
195 while (*p && !iswdigit( *p )) p++;
196 if ((q = wcschr( p, '.' )))
197 {
198 major = wcstol( p, NULL, 10 );
199 p = ++q;
200 while (*q && iswdigit( *q )) q++;
201 if (!*q || *q == ' ') minor = wcstol( p, NULL, 10 );
202 else major = 0;
203 }
204 len = lstrlenW( L"%u.%u.0.0" ) + 20;
205 ret = msi_alloc( len * sizeof(WCHAR) );
206 swprintf( ret, len, L"%u.%u.0.0", major, minor );
207 msi_free( version );
208 }
209 return ret;
210}
211
213{
214 MSIPACKAGE *package = param;
215 LPWSTR name;
217 MSIFILE *file;
218 MSICOMPONENT *comp;
219 HKEY hkey1, hkey2;
220 MSIRECORD *uirow;
221 LPWSTR uipath, p;
222
224 file = msi_get_loaded_file( package, filename );
225 if (!file)
226 {
227 WARN("unable to find file %s\n", debugstr_w(filename));
228 return ERROR_SUCCESS;
229 }
230 comp = msi_get_loaded_component( package, file->Component->Component );
231 if (!comp)
232 {
233 WARN("unable to find component %s\n", debugstr_w(file->Component->Component));
234 return ERROR_SUCCESS;
235 }
236 comp->Action = msi_get_component_action( package, comp );
237 if (comp->Action != INSTALLSTATE_LOCAL)
238 {
239 TRACE("component not scheduled for installation %s\n", debugstr_w(comp->Component));
240 return ERROR_SUCCESS;
241 }
242
243 RegCreateKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts" ,&hkey1 );
244 RegCreateKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Fonts", &hkey2 );
245
246 if (MSI_RecordIsNull(row,2))
247 name = font_name_from_file( package, file->TargetPath );
248 else
250
251 if (name)
252 {
253 msi_reg_set_val_str( hkey1, name, file->TargetPath);
254 msi_reg_set_val_str( hkey2, name, file->TargetPath);
255 }
256
257 msi_free(name);
258 RegCloseKey(hkey1);
259 RegCloseKey(hkey2);
260
261 /* the UI chunk */
262 uirow = MSI_CreateRecord( 1 );
263 uipath = strdupW( file->TargetPath );
264 p = wcsrchr(uipath,'\\');
265 if (p) p++;
266 else p = uipath;
267 MSI_RecordSetStringW( uirow, 1, p );
269 msiobj_release( &uirow->hdr );
270 msi_free( uipath );
271 /* FIXME: call msi_ui_progress? */
272
273 return ERROR_SUCCESS;
274}
275
277{
278 MSIQUERY *view;
279 UINT rc;
280
281 if (package->script == SCRIPT_NONE)
282 return msi_schedule_action(package, SCRIPT_INSTALL, L"RegisterFonts");
283
284 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Font`", &view);
285 if (rc != ERROR_SUCCESS)
286 return ERROR_SUCCESS;
287
289 msiobj_release(&view->hdr);
290 return rc;
291}
292
294{
295 MSIPACKAGE *package = param;
296 LPWSTR name;
298 MSIFILE *file;
299 MSICOMPONENT *comp;
300 HKEY hkey1, hkey2;
301 MSIRECORD *uirow;
302 LPWSTR uipath, p;
303
305 file = msi_get_loaded_file( package, filename );
306 if (!file)
307 {
308 WARN("unable to find file %s\n", debugstr_w(filename));
309 return ERROR_SUCCESS;
310 }
311 comp = msi_get_loaded_component( package, file->Component->Component );
312 if (!comp)
313 {
314 WARN("unable to find component %s\n", debugstr_w(file->Component->Component));
315 return ERROR_SUCCESS;
316 }
317 comp->Action = msi_get_component_action( package, comp );
318 if (comp->Action != INSTALLSTATE_ABSENT)
319 {
320 TRACE("component not scheduled for removal %s\n", debugstr_w(comp->Component));
321 return ERROR_SUCCESS;
322 }
323
324 RegCreateKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts", &hkey1 );
325 RegCreateKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Fonts", &hkey2 );
326
327 if (MSI_RecordIsNull( row, 2 ))
328 name = font_name_from_file( package, file->TargetPath );
329 else
331
332 if (name)
333 {
334 RegDeleteValueW( hkey1, name );
335 RegDeleteValueW( hkey2, name );
336 }
337
338 msi_free( name );
339 RegCloseKey( hkey1 );
340 RegCloseKey( hkey2 );
341
342 /* the UI chunk */
343 uirow = MSI_CreateRecord( 1 );
344 uipath = strdupW( file->TargetPath );
345 p = wcsrchr( uipath,'\\' );
346 if (p) p++;
347 else p = uipath;
348 MSI_RecordSetStringW( uirow, 1, p );
350 msiobj_release( &uirow->hdr );
351 msi_free( uipath );
352 /* FIXME: call msi_ui_progress? */
353
354 return ERROR_SUCCESS;
355}
356
358{
359 MSIQUERY *view;
360 UINT r;
361
362 if (package->script == SCRIPT_NONE)
363 return msi_schedule_action(package, SCRIPT_INSTALL, L"UnregisterFonts");
364
365 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Font`", &view );
366 if (r != ERROR_SUCCESS)
367 return ERROR_SUCCESS;
368
370 msiobj_release( &view->hdr );
371 return r;
372}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
#define CloseHandle
Definition: compat.h:739
#define wcschr
Definition: compat.h:17
#define FILE_BEGIN
Definition: compat.h:761
#define wcsrchr
Definition: compat.h:16
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
static const WCHAR version[]
Definition: asmname.c:66
#define NAME_ID_FULL_FONT_NAME
Definition: font.c:1185
static WCHAR * load_ttf_name_id(const BYTE *mem, DWORD_PTR size, DWORD id)
Definition: font.c:1426
INSTALLSTATE msi_get_component_action(MSIPACKAGE *package, MSICOMPONENT *comp)
Definition: action.c:611
MSICOMPONENT * msi_get_loaded_component(MSIPACKAGE *package, const WCHAR *Component)
Definition: action.c:552
MSIFILE * msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *key)
Definition: action.c:574
UINT msi_schedule_action(MSIPACKAGE *package, UINT script, const WCHAR *action)
Definition: custom.c:90
HANDLE msi_create_file(MSIPACKAGE *package, const WCHAR *filename, DWORD access, DWORD sharing, DWORD creation, DWORD flags)
Definition: files.c:51
struct _tagTT_NAME_RECORD TT_NAME_RECORD
static WCHAR * font_name_from_file(MSIPACKAGE *package, const WCHAR *filename)
Definition: font.c:166
#define SWAPLONG(x)
Definition: font.c:67
WCHAR * msi_get_font_file_version(MSIPACKAGE *package, const WCHAR *filename)
Definition: font.c:186
struct _tagTT_NAME_TABLE_HEADER TT_NAME_TABLE_HEADER
static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
Definition: font.c:212
struct _tagTT_OFFSET_TABLE TT_OFFSET_TABLE
#define NAME_ID_VERSION
Definition: font.c:55
#define SWAPWORD(x)
Definition: font.c:66
struct _tagTT_TABLE_DIRECTORY TT_TABLE_DIRECTORY
UINT ACTION_UnregisterFonts(MSIPACKAGE *package)
Definition: font.c:357
static UINT ITERATE_UnregisterFonts(MSIRECORD *row, LPVOID param)
Definition: font.c:293
UINT ACTION_RegisterFonts(MSIPACKAGE *package)
Definition: font.c:276
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
#define swprintf
Definition: precomp.h:40
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define iswdigit(_c)
Definition: ctype.h:667
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
const char * filename
Definition: ioapi.h:137
#define debugstr_w
Definition: kernel32.h:32
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
@ INSTALLMESSAGE_ACTIONDATA
Definition: msi.h:103
@ INSTALLSTATE_LOCAL
Definition: msi.h:46
@ INSTALLSTATE_ABSENT
Definition: msi.h:45
WCHAR * msi_dup_record_field(MSIRECORD *row, INT index) DECLSPEC_HIDDEN
Definition: record.c:1002
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1148
UINT MSI_IterateRecords(MSIQUERY *, LPDWORD, record_func, LPVOID) DECLSPEC_HIDDEN
Definition: msiquery.c:163
static void msi_free(void *mem)
Definition: msipriv.h:1159
@ SCRIPT_INSTALL
Definition: msipriv.h:385
@ SCRIPT_NONE
Definition: msipriv.h:384
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:433
INT MSI_ProcessMessage(MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD *) DECLSPEC_HIDDEN
Definition: package.c:1914
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
Definition: record.c:76
BOOL MSI_RecordIsNull(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:321
LONG msi_reg_set_val_str(HKEY hkey, LPCWSTR name, LPCWSTR value) DECLSPEC_HIDDEN
Definition: registry.c:209
UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY **) DECLSPEC_HIDDEN
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
Definition: record.c:597
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define minor(rdev)
Definition: propsheet.cpp:929
#define major(rdev)
Definition: propsheet.cpp:928
#define TRACE(s)
Definition: solgame.cpp:4
USHORT uStringLength
Definition: font.c:62
USHORT uEncodingID
Definition: font.c:59
USHORT uLanguageID
Definition: font.c:60
USHORT uStringOffset
Definition: font.c:63
USHORT uNameID
Definition: font.c:61
USHORT uPlatformID
Definition: font.c:58
USHORT uStorageOffset
Definition: font.c:50
USHORT uMajorVersion
Definition: font.c:32
USHORT uMinorVersion
Definition: font.c:33
USHORT uNumOfTables
Definition: font.c:34
USHORT uSearchRange
Definition: font.c:35
USHORT uRangeShift
Definition: font.c:37
USHORT uEntrySelector
Definition: font.c:36
Definition: fci.c:127
Definition: name.c:39
LPWSTR Component
Definition: msipriv.h:525
INSTALLSTATE Action
Definition: msipriv.h:533
MSIDATABASE * db
Definition: msipriv.h:394
enum script script
Definition: msipriv.h:432
MSIOBJECTHDR hdr
Definition: msipriv.h:151
uint32_t ULONG
Definition: typedefs.h:59
int ret
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185