ReactOS 0.4.16-dev-732-g2d1144a
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
32{
39};
40
42{
43 char szTag[4]; /* table name */
44 ULONG uCheckSum; /* Check sum */
45 ULONG uOffset; /* Offset from beginning of file */
46 ULONG uLength; /* length of the table in bytes */
47};
48
50{
51 USHORT uFSelector; /* format selector. Always 0 */
52 USHORT uNRCount; /* Name Records count */
53 USHORT uStorageOffset; /* Offset for strings storage from start of the table */
54};
55
56#define NAME_ID_FULL_FONT_NAME 4
57#define NAME_ID_VERSION 5
58
60{
66 USHORT uStringOffset; /* from start of storage area */
67};
68
69#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
70#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
71
72/*
73 * Code based off of code located here
74 * http://www.codeproject.com/gdi/fontnamefromfile.asp
75 */
76static WCHAR *load_ttf_name_id( MSIPACKAGE *package, const WCHAR *filename, DWORD id )
77{
78 struct table_directory tblDir;
79 BOOL bFound = FALSE;
80 struct offset_table ttOffsetTable;
81 struct name_table_header ttNTHeader;
82 struct name_record ttRecord;
83 DWORD dwRead;
85 LPWSTR ret = NULL;
86 int i;
87
88 if (package)
90 else
93 {
94 ERR("Unable to open font file %s\n", debugstr_w(filename));
95 return NULL;
96 }
97
98 if (!ReadFile(handle,&ttOffsetTable, sizeof(struct offset_table),&dwRead,NULL))
99 goto end;
100
101 ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);
102 ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);
103 ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);
104
105 if ((ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0) &&
106 (ttOffsetTable.uMajorVersion != 0x4f54 || ttOffsetTable.uMinorVersion != 0x544f))
107 goto end;
108
109 for (i=0; i< ttOffsetTable.uNumOfTables; i++)
110 {
111 if (!ReadFile(handle, &tblDir, sizeof(tblDir), &dwRead, NULL))
112 break;
113 if (memcmp(tblDir.szTag,"name",4)==0)
114 {
115 bFound = TRUE;
116 tblDir.uLength = SWAPLONG(tblDir.uLength);
117 tblDir.uOffset = SWAPLONG(tblDir.uOffset);
118 break;
119 }
120 }
121
122 if (!bFound)
123 goto end;
124
126 if (!ReadFile(handle, &ttNTHeader, sizeof(ttNTHeader), &dwRead, NULL))
127 goto end;
128
129 ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
130 ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
131 for(i=0; i<ttNTHeader.uNRCount; i++)
132 {
133 if (!ReadFile(handle, &ttRecord, sizeof(ttRecord), &dwRead, NULL))
134 break;
135
136 ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
137 ttRecord.uPlatformID = SWAPWORD(ttRecord.uPlatformID);
138 ttRecord.uEncodingID = SWAPWORD(ttRecord.uEncodingID);
139 if (ttRecord.uNameID == id && ttRecord.uPlatformID == 3 &&
140 (ttRecord.uEncodingID == 0 || ttRecord.uEncodingID == 1))
141 {
142 WCHAR *buf;
143 unsigned int i;
144
145 ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
146 ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
147 SetFilePointer(handle, tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset,
149 if (!(buf = calloc(ttRecord.uStringLength, sizeof(WCHAR)))) goto end;
150 dwRead = 0;
151 ReadFile(handle, buf, ttRecord.uStringLength, &dwRead, NULL);
152 if (dwRead % sizeof(WCHAR))
153 {
154 free(buf);
155 goto end;
156 }
157 for (i = 0; i < dwRead / sizeof(WCHAR); i++) buf[i] = SWAPWORD(buf[i]);
158 ret = wcsdup(buf);
159 free(buf);
160 break;
161 }
162 }
163
164end:
166 return ret;
167}
168
170{
171 WCHAR *name, *ret = NULL;
172
174 {
175 if (!name[0])
176 {
177 WARN("empty font name\n");
178 free( name );
179 return NULL;
180 }
181 ret = malloc( wcslen( name ) * sizeof(WCHAR) + sizeof( L" (TrueType)" ) );
182 lstrcpyW( ret, name );
183 lstrcatW( ret, L" (TrueType)" );
184 free( name );
185 }
186 return ret;
187}
188
190{
191 WCHAR *version, *p, *q, *ret = NULL;
192
194 {
195 int len, major = 0, minor = 0;
196 if ((p = wcschr( version, ';' ))) *p = 0;
197 p = version;
198 while (*p && !iswdigit( *p )) p++;
199 if ((q = wcschr( p, '.' )))
200 {
201 major = wcstol( p, NULL, 10 );
202 p = ++q;
203 while (*q && iswdigit( *q )) q++;
204 if (!*q || *q == ' ') minor = wcstol( p, NULL, 10 );
205 else major = 0;
206 }
207 len = lstrlenW( L"%u.%u.0.0" ) + 20;
208 ret = malloc( len * sizeof(WCHAR) );
209 swprintf( ret, len, L"%u.%u.0.0", major, minor );
210 free( version );
211 }
212 return ret;
213}
214
216{
217 MSIPACKAGE *package = param;
218 LPWSTR name;
220 MSIFILE *file;
221 MSICOMPONENT *comp;
222 HKEY hkey1, hkey2;
223 MSIRECORD *uirow;
224 LPWSTR uipath, p;
225
227 file = msi_get_loaded_file( package, filename );
228 if (!file)
229 {
230 WARN("unable to find file %s\n", debugstr_w(filename));
231 return ERROR_SUCCESS;
232 }
233 comp = msi_get_loaded_component( package, file->Component->Component );
234 if (!comp)
235 {
236 WARN("unable to find component %s\n", debugstr_w(file->Component->Component));
237 return ERROR_SUCCESS;
238 }
239 comp->Action = msi_get_component_action( package, comp );
240 if (comp->Action != INSTALLSTATE_LOCAL)
241 {
242 TRACE("component not scheduled for installation %s\n", debugstr_w(comp->Component));
243 return ERROR_SUCCESS;
244 }
245
246 RegCreateKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts" ,&hkey1 );
247 RegCreateKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Fonts", &hkey2 );
248
249 if (MSI_RecordIsNull(row,2))
250 name = font_name_from_file( package, file->TargetPath );
251 else
253
254 if (name)
255 {
256 msi_reg_set_val_str( hkey1, name, file->TargetPath);
257 msi_reg_set_val_str( hkey2, name, file->TargetPath);
258 }
259
260 free(name);
261 RegCloseKey(hkey1);
262 RegCloseKey(hkey2);
263
264 /* the UI chunk */
265 uirow = MSI_CreateRecord( 1 );
266 uipath = wcsdup( file->TargetPath );
267 p = wcsrchr(uipath,'\\');
268 if (p) p++;
269 else p = uipath;
270 MSI_RecordSetStringW( uirow, 1, p );
272 msiobj_release( &uirow->hdr );
273 free( uipath );
274 /* FIXME: call msi_ui_progress? */
275
276 return ERROR_SUCCESS;
277}
278
280{
281 MSIQUERY *view;
282 UINT rc;
283
284 if (package->script == SCRIPT_NONE)
285 return msi_schedule_action(package, SCRIPT_INSTALL, L"RegisterFonts");
286
287 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Font`", &view);
288 if (rc != ERROR_SUCCESS)
289 return ERROR_SUCCESS;
290
292 msiobj_release(&view->hdr);
293 return rc;
294}
295
297{
298 MSIPACKAGE *package = param;
299 LPWSTR name;
301 MSIFILE *file;
302 MSICOMPONENT *comp;
303 HKEY hkey1, hkey2;
304 MSIRECORD *uirow;
305 LPWSTR uipath, p;
306
308 file = msi_get_loaded_file( package, filename );
309 if (!file)
310 {
311 WARN("unable to find file %s\n", debugstr_w(filename));
312 return ERROR_SUCCESS;
313 }
314 comp = msi_get_loaded_component( package, file->Component->Component );
315 if (!comp)
316 {
317 WARN("unable to find component %s\n", debugstr_w(file->Component->Component));
318 return ERROR_SUCCESS;
319 }
320 comp->Action = msi_get_component_action( package, comp );
321 if (comp->Action != INSTALLSTATE_ABSENT)
322 {
323 TRACE("component not scheduled for removal %s\n", debugstr_w(comp->Component));
324 return ERROR_SUCCESS;
325 }
326
327 RegCreateKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts", &hkey1 );
328 RegCreateKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Fonts", &hkey2 );
329
330 if (MSI_RecordIsNull( row, 2 ))
331 name = font_name_from_file( package, file->TargetPath );
332 else
334
335 if (name)
336 {
337 RegDeleteValueW( hkey1, name );
338 RegDeleteValueW( hkey2, name );
339 }
340
341 free( name );
342 RegCloseKey( hkey1 );
343 RegCloseKey( hkey2 );
344
345 /* the UI chunk */
346 uirow = MSI_CreateRecord( 1 );
347 uipath = wcsdup( file->TargetPath );
348 p = wcsrchr( uipath,'\\' );
349 if (p) p++;
350 else p = uipath;
351 MSI_RecordSetStringW( uirow, 1, p );
353 msiobj_release( &uirow->hdr );
354 free( uipath );
355 /* FIXME: call msi_ui_progress? */
356
357 return ERROR_SUCCESS;
358}
359
361{
362 MSIQUERY *view;
363 UINT r;
364
365 if (package->script == SCRIPT_NONE)
366 return msi_schedule_action(package, SCRIPT_INSTALL, L"UnregisterFonts");
367
368 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Font`", &view );
369 if (r != ERROR_SUCCESS)
370 return ERROR_SUCCESS;
371
373 msiobj_release( &view->hdr );
374 return r;
375}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define RegCloseKey(hKey)
Definition: registry.h:49
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#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:609
MSICOMPONENT * msi_get_loaded_component(MSIPACKAGE *package, const WCHAR *Component)
Definition: action.c:550
MSIFILE * msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *key)
Definition: action.c:572
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:60
static WCHAR * font_name_from_file(MSIPACKAGE *package, const WCHAR *filename)
Definition: font.c:169
#define SWAPLONG(x)
Definition: font.c:70
WCHAR * msi_get_font_file_version(MSIPACKAGE *package, const WCHAR *filename)
Definition: font.c:189
static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
Definition: font.c:215
#define NAME_ID_VERSION
Definition: font.c:57
#define SWAPWORD(x)
Definition: font.c:69
UINT ACTION_UnregisterFonts(MSIPACKAGE *package)
Definition: font.c:360
static UINT ITERATE_UnregisterFonts(MSIRECORD *row, LPVOID param)
Definition: font.c:296
UINT ACTION_RegisterFonts(MSIPACKAGE *package)
Definition: font.c:279
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)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
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)
Definition: record.c:1002
@ SCRIPT_INSTALL
Definition: msipriv.h:385
@ SCRIPT_NONE
Definition: msipriv.h:384
UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY **)
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT)
Definition: record.c:433
LONG msi_reg_set_val_str(HKEY hkey, LPCWSTR name, LPCWSTR value)
Definition: registry.c:209
BOOL MSI_RecordIsNull(MSIRECORD *, UINT)
Definition: record.c:321
INT MSI_ProcessMessage(MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD *)
Definition: package.c:1909
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR)
Definition: record.c:597
MSIRECORD * MSI_CreateRecord(UINT)
Definition: record.c:76
UINT MSI_IterateRecords(MSIQUERY *, LPDWORD, record_func, LPVOID)
Definition: msiquery.c:163
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define calloc
Definition: rosglue.h:14
_Check_return_ _CRTIMP wchar_t *__cdecl wcsdup(_In_z_ const wchar_t *_Str)
#define minor(rdev)
Definition: propsheet.cpp:929
#define major(rdev)
Definition: propsheet.cpp:928
#define TRACE(s)
Definition: solgame.cpp:4
Definition: fci.c:127
USHORT uEncodingID
Definition: font.c:62
USHORT uNameID
Definition: font.c:64
USHORT uStringOffset
Definition: font.c:66
USHORT uLanguageID
Definition: font.c:63
USHORT uPlatformID
Definition: font.c:61
USHORT uStringLength
Definition: font.c:65
USHORT uStorageOffset
Definition: font.c:53
USHORT uNRCount
Definition: font.c:52
USHORT uFSelector
Definition: font.c:51
Definition: name.c:39
USHORT uEntrySelector
Definition: font.c:37
USHORT uNumOfTables
Definition: font.c:35
USHORT uRangeShift
Definition: font.c:38
USHORT uSearchRange
Definition: font.c:36
USHORT uMajorVersion
Definition: font.c:33
USHORT uMinorVersion
Definition: font.c:34
ULONG uOffset
Definition: font.c:45
char szTag[4]
Definition: font.c:43
ULONG uCheckSum
Definition: font.c:44
ULONG uLength
Definition: font.c:46
LPWSTR Component
Definition: msipriv.h:524
INSTALLSTATE Action
Definition: msipriv.h:532
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