ReactOS 0.4.17-dev-966-gf06eace
appsearch.c File Reference
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "msi.h"
#include "msiquery.h"
#include "msidefs.h"
#include "winver.h"
#include "shlwapi.h"
#include "wine/debug.h"
#include "msipriv.h"
Include dependency graph for appsearch.c:

Go to the source code of this file.

Classes

struct  signature
 

Macros

#define COBJMACROS
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msi)
 
void msi_parse_version_string (LPCWSTR verStr, PDWORD ms, PDWORD ls)
 
static UINT get_signature (MSIPACKAGE *package, struct signature *sig, const WCHAR *name)
 
static void free_signature (struct signature *sig)
 
static WCHAR * search_file (MSIPACKAGE *package, WCHAR *path, struct signature *sig)
 
static UINT search_components (MSIPACKAGE *package, WCHAR **appValue, struct signature *sig)
 
static void convert_reg_value (DWORD regType, const BYTE *value, DWORD sz, WCHAR **appValue)
 
static UINT search_directory (MSIPACKAGE *, struct signature *, const WCHAR *, int, WCHAR **)
 
static UINT search_reg (MSIPACKAGE *package, WCHAR **appValue, struct signature *sig)
 
static LPWSTR get_ini_field (LPWSTR buf, int field)
 
static UINT search_ini (MSIPACKAGE *package, WCHAR **appValue, struct signature *sig)
 
static void expand_any_path (MSIPACKAGE *package, WCHAR *src, WCHAR *dst, size_t len)
 
static LANGID * parse_languages (const WCHAR *languages, DWORD *num_ids)
 
static BOOL match_languages (const void *version, const WCHAR *languages)
 
static UINT file_version_matches (MSIPACKAGE *package, const struct signature *sig, const WCHAR *filePath, BOOL *matches)
 
static UINT file_matches_sig (MSIPACKAGE *package, const struct signature *sig, const WIN32_FIND_DATAW *findData, const WCHAR *fullFilePath, BOOL *matches)
 
static UINT recurse_search_directory (MSIPACKAGE *package, WCHAR **appValue, struct signature *sig, const WCHAR *dir, int depth)
 
static UINT check_directory (MSIPACKAGE *package, const WCHAR *dir, WCHAR **appValue)
 
static BOOL is_full_path (const WCHAR *path)
 
static UINT load_drlocator (MSIRECORD *row, void *param)
 
static UINT load_all_drlocators (MSIPACKAGE *package)
 
static void free_drlocators (MSIPACKAGE *package)
 
static UINT search_sig_name (MSIPACKAGE *, const WCHAR *, struct signature *, WCHAR **)
 
static UINT search_dr (MSIPACKAGE *package, WCHAR **app_value, struct signature *sig)
 
static UINT ITERATE_AppSearch (MSIRECORD *row, LPVOID param)
 
UINT ACTION_AppSearch (MSIPACKAGE *package)
 
static UINT ITERATE_CCPSearch (MSIRECORD *row, LPVOID param)
 
UINT ACTION_CCPSearch (MSIPACKAGE *package)
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 22 of file appsearch.c.

Function Documentation

◆ ACTION_AppSearch()

UINT ACTION_AppSearch ( MSIPACKAGE *  package)

Definition at line 1124 of file appsearch.c.

1125{
1126 MSIQUERY *view;
1127 UINT r;
1128
1129 if (msi_action_is_unique(package, L"AppSearch"))
1130 {
1131 TRACE("Skipping AppSearch action: already done in UI sequence\n");
1132 return ERROR_SUCCESS;
1133 }
1134 else
1135 msi_register_unique_action(package, L"AppSearch");
1136
1137 r = MSI_OpenQuery( package->db, &view, L"SELECT * FROM `AppSearch`" );
1138 if (r != ERROR_SUCCESS)
1139 return ERROR_SUCCESS;
1140
1142 msiobj_release( &view->hdr );
1143 return r;
1144}
static UINT ITERATE_AppSearch(MSIRECORD *row, LPVOID param)
Definition: appsearch.c:1086
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
UINT msi_register_unique_action(MSIPACKAGE *package, const WCHAR *action)
Definition: custom.c:112
BOOL msi_action_is_unique(const MSIPACKAGE *package, const WCHAR *action)
Definition: custom.c:130
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
#define L(x)
Definition: resources.c:13
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
unsigned int UINT
Definition: sysinfo.c:13
UINT WINAPIV MSI_OpenQuery(MSIDATABASE *, MSIQUERY **, LPCWSTR,...)
Definition: msiquery.c:138
UINT MSI_IterateRecords(MSIQUERY *, LPDWORD, record_func, LPVOID)
Definition: msiquery.c:163
#define TRACE(s)
Definition: solgame.cpp:4
MSIDATABASE * db
Definition: msipriv.h:407

◆ ACTION_CCPSearch()

UINT ACTION_CCPSearch ( MSIPACKAGE *  package)

Definition at line 1174 of file appsearch.c.

1175{
1176 MSIQUERY *view;
1177 UINT r;
1178
1179 if (msi_action_is_unique(package, L"CCPSearch"))
1180 {
1181 TRACE("Skipping AppSearch action: already done in UI sequence\n");
1182 return ERROR_SUCCESS;
1183 }
1184 else
1185 msi_register_unique_action(package, L"CCPSearch");
1186
1187 r = MSI_OpenQuery(package->db, &view, L"SELECT * FROM `CCPSearch`");
1188 if (r != ERROR_SUCCESS)
1189 return ERROR_SUCCESS;
1190
1192 msiobj_release(&view->hdr);
1193 return r;
1194}
static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param)
Definition: appsearch.c:1146

◆ check_directory()

static UINT check_directory ( MSIPACKAGE *  package,
const WCHAR *  dir,
WCHAR **  appValue 
)
static

Definition at line 847 of file appsearch.c.

848{
850
852 {
853 TRACE("directory exists, returning %s\n", debugstr_w(dir));
854 *appValue = wcsdup(dir);
855 }
856
857 return ERROR_SUCCESS;
858}
unsigned int dir
Definition: maze.c:112
DWORD msi_get_file_attributes(MSIPACKAGE *package, const WCHAR *path)
Definition: files.c:115
static wchar_t * wcsdup(const wchar_t *str)
Definition: string.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define debugstr_w
Definition: kernel32.h:32
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
Definition: cookie.c:202
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23

Referenced by main(), and search_directory().

◆ convert_reg_value()

static void convert_reg_value ( DWORD  regType,
const BYTE *  value,
DWORD  sz,
WCHAR **  appValue 
)
static

Definition at line 297 of file appsearch.c.

298{
299 LPWSTR ptr;
300 DWORD i;
301
302 switch (regType)
303 {
304 case REG_SZ:
305 if (*(LPCWSTR)value == '#')
306 {
307 /* escape leading pound with another */
308 *appValue = malloc(sz + sizeof(WCHAR));
309 (*appValue)[0] = '#';
310 lstrcpyW(*appValue + 1, (LPCWSTR)value);
311 }
312 else
313 {
314 *appValue = malloc(sz);
315 lstrcpyW(*appValue, (LPCWSTR)value);
316 }
317 break;
318 case REG_DWORD:
319 /* 7 chars for digits, 1 for NULL, 1 for #, and 1 for sign
320 * char if needed
321 */
322 *appValue = malloc(10 * sizeof(WCHAR));
323 swprintf(*appValue, 10, L"#%d", *(const DWORD *)value);
324 break;
325 case REG_EXPAND_SZ:
327 *appValue = malloc(sz * sizeof(WCHAR));
328 ExpandEnvironmentStringsW((LPCWSTR)value, *appValue, sz);
329 break;
330 case REG_BINARY:
331 /* #x<nibbles>\0 */
332 *appValue = malloc((sz * 2 + 3) * sizeof(WCHAR));
333 lstrcpyW(*appValue, L"#x");
334 ptr = *appValue + lstrlenW(L"#x");
335 for (i = 0; i < sz; i++, ptr += 2)
336 swprintf(ptr, 3, L"%02X", value[i]);
337 break;
338 default:
339 WARN( "unimplemented for values of type %lu\n", regType );
340 *appValue = NULL;
341 }
342}
#define REG_SZ
Definition: layer.c:22
#define WARN(fmt,...)
Definition: precomp.h:61
#define malloc
Definition: debug_ros.c:4
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:492
#define swprintf
Definition: precomp.h:40
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
static PVOID ptr
Definition: dispmode.c:27
#define REG_BINARY
Definition: nt_native.h:1499
#define REG_EXPAND_SZ
Definition: nt_native.h:1497
short WCHAR
Definition: pedump.c:58
#define REG_DWORD
Definition: sdbapi.c:615
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
Definition: pdh_main.c:64

Referenced by search_reg().

◆ expand_any_path()

static void expand_any_path ( MSIPACKAGE *  package,
WCHAR *  src,
WCHAR *  dst,
size_t  len 
)
static

Definition at line 560 of file appsearch.c.

561{
562 WCHAR *ptr, *deformatted;
563
564 if (!src || !dst || !len)
565 {
566 if (dst) *dst = '\0';
567 return;
568 }
569
570 dst[0] = '\0';
571
572 /* Ignore the short portion of the path */
573 if ((ptr = wcschr(src, '|')))
574 ptr++;
575 else
576 ptr = src;
577
578 deformat_string(package, ptr, &deformatted);
579 if (!deformatted || lstrlenW(deformatted) > len - 1)
580 {
581 free(deformatted);
582 return;
583 }
584
585 lstrcpyW(dst, deformatted);
586 dst[lstrlenW(deformatted)] = '\0';
587 free(deformatted);
588}
#define free
Definition: debug_ros.c:5
#define wcschr
Definition: compat.h:17
DWORD deformat_string(MSIPACKAGE *package, const WCHAR *fmt, WCHAR **data)
Definition: format.c:1015
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
GLenum GLsizei len
Definition: glext.h:6722

Referenced by search_dr().

◆ file_matches_sig()

static UINT file_matches_sig ( MSIPACKAGE *  package,
const struct signature *  sig,
const WIN32_FIND_DATAW *  findData,
const WCHAR *  fullFilePath,
BOOL *  matches 
)
static

Definition at line 715 of file appsearch.c.

717{
718 UINT rc = ERROR_SUCCESS;
719
720 *matches = TRUE;
721 /* assumes the caller has already ensured the filenames match, so check
722 * the other fields..
723 */
725 {
726 if (findData->ftCreationTime.dwHighDateTime <
727 sig->MinTime.dwHighDateTime ||
729 && findData->ftCreationTime.dwLowDateTime <
731 *matches = FALSE;
732 }
733 if (*matches && (sig->MaxTime.dwLowDateTime || sig->MaxTime.dwHighDateTime))
734 {
735 if (findData->ftCreationTime.dwHighDateTime >
736 sig->MaxTime.dwHighDateTime ||
738 && findData->ftCreationTime.dwLowDateTime >
740 *matches = FALSE;
741 }
742 if (*matches && sig->MinSize && findData->nFileSizeLow < sig->MinSize)
743 *matches = FALSE;
744 if (*matches && sig->MaxSize && findData->nFileSizeLow > sig->MaxSize)
745 *matches = FALSE;
746 if (*matches && (sig->MinVersionMS || sig->MinVersionLS ||
747 sig->MaxVersionMS || sig->MaxVersionLS))
748 rc = file_version_matches( package, sig, fullFilePath, matches );
749 return rc;
750}
static UINT file_version_matches(MSIPACKAGE *package, const struct signature *sig, const WCHAR *filePath, BOOL *matches)
Definition: appsearch.c:655
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define matches(FN)
Definition: match.h:70
DWORD dwHighDateTime
Definition: mapidefs.h:66
DWORD dwLowDateTime
Definition: mapidefs.h:65
FILETIME ftCreationTime
Definition: minwinbase.h:284
DWORD MinVersionLS
Definition: appsearch.c:42
DWORD MaxVersionMS
Definition: appsearch.c:43
DWORD MaxSize
Definition: appsearch.c:46
DWORD MinVersionMS
Definition: appsearch.c:41
DWORD MaxVersionLS
Definition: appsearch.c:44
DWORD MinSize
Definition: appsearch.c:45
FILETIME MaxTime
Definition: appsearch.c:48
FILETIME MinTime
Definition: appsearch.c:47

Referenced by recurse_search_directory().

◆ file_version_matches()

static UINT file_version_matches ( MSIPACKAGE *  package,
const struct signature *  sig,
const WCHAR *  filePath,
BOOL *  matches 
)
static

Definition at line 655 of file appsearch.c.

657{
658 UINT len;
659 void *version;
661 DWORD size = msi_get_file_version_info( package, filePath, 0, NULL );
662
663 *matches = FALSE;
664
665 if (!size) return ERROR_SUCCESS;
666 if (!(version = malloc( size ))) return ERROR_OUTOFMEMORY;
667
668 if (msi_get_file_version_info( package, filePath, size, version ))
669 VerQueryValueW( version, L"\\", (void **)&info, &len );
670
671 if (info)
672 {
673 TRACE("comparing file version %d.%d.%d.%d:\n",
674 HIWORD(info->dwFileVersionMS),
675 LOWORD(info->dwFileVersionMS),
676 HIWORD(info->dwFileVersionLS),
677 LOWORD(info->dwFileVersionLS));
678 if (info->dwFileVersionMS < sig->MinVersionMS
679 || (info->dwFileVersionMS == sig->MinVersionMS &&
680 info->dwFileVersionLS < sig->MinVersionLS))
681 {
682 TRACE("less than minimum version %d.%d.%d.%d\n",
683 HIWORD(sig->MinVersionMS),
684 LOWORD(sig->MinVersionMS),
685 HIWORD(sig->MinVersionLS),
686 LOWORD(sig->MinVersionLS));
687 }
688 else if ((sig->MaxVersionMS || sig->MaxVersionLS) &&
689 (info->dwFileVersionMS > sig->MaxVersionMS ||
690 (info->dwFileVersionMS == sig->MaxVersionMS &&
691 info->dwFileVersionLS > sig->MaxVersionLS)))
692 {
693 TRACE("greater than maximum version %d.%d.%d.%d\n",
694 HIWORD(sig->MaxVersionMS),
695 LOWORD(sig->MaxVersionMS),
696 HIWORD(sig->MaxVersionLS),
697 LOWORD(sig->MaxVersionLS));
698 }
699 else if (!match_languages( version, sig->Languages ))
700 {
701 TRACE("languages %s not supported\n", debugstr_w( sig->Languages ));
702 }
703 else *matches = TRUE;
704 }
705 free( version );
706 return ERROR_SUCCESS;
707}
static BOOL match_languages(const void *version, const WCHAR *languages)
Definition: appsearch.c:619
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
static const WCHAR version[]
Definition: asmname.c:66
BOOL WINAPI VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:1171
DWORD msi_get_file_version_info(MSIPACKAGE *package, const WCHAR *path, DWORD buflen, BYTE *buffer)
Definition: files.c:160
GLsizeiptr size
Definition: glext.h:5919
#define LOWORD(l)
Definition: pedump.c:82
LPWSTR Languages
Definition: appsearch.c:49
#define HIWORD(l)
Definition: typedefs.h:247

Referenced by file_matches_sig().

◆ free_drlocators()

static void free_drlocators ( MSIPACKAGE *  package)
static

Definition at line 979 of file appsearch.c.

980{
981 struct list *item, *cursor;
982
984 {
986
987 list_remove( &locator->entry );
988 free( locator->Signature );
989 free( locator->Parent );
990 free( locator->Path );
991 free( locator );
992 }
993}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
Definition: list.h:39
const char cursor[]
Definition: icontest.c:13
uint32_t entry
Definition: isohybrid.c:63
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:230
struct list drlocators
Definition: msipriv.h:422
#define LIST_ENTRY(type)
Definition: queue.h:175

Referenced by ITERATE_AppSearch(), and ITERATE_CCPSearch().

◆ free_signature()

static void free_signature ( struct signature *  sig)
static

Definition at line 151 of file appsearch.c.

152{
153 free(sig->File);
154 free(sig->Languages);
155}
LPWSTR File
Definition: appsearch.c:40

Referenced by search_dr().

◆ get_ini_field()

static LPWSTR get_ini_field ( LPWSTR  buf,
int  field 
)
static

Definition at line 471 of file appsearch.c.

472{
473 LPWSTR beg, end;
474 int i = 1;
475
476 if (field == 0)
477 return wcsdup(buf);
478
479 beg = buf;
480 while ((end = wcschr(beg, ',')) && i < field)
481 {
482 beg = end + 1;
483 while (*beg == ' ')
484 beg++;
485
486 i++;
487 }
488
489 end = wcschr(beg, ',');
490 if (!end)
491 end = beg + lstrlenW(beg);
492
493 *end = '\0';
494 return wcsdup(beg);
495}
GLuint GLuint end
Definition: gl.h:1545
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
Definition: parser.c:44

Referenced by search_ini().

◆ get_signature()

static UINT get_signature ( MSIPACKAGE *  package,
struct signature *  sig,
const WCHAR *  name 
)
static

Definition at line 83 of file appsearch.c.

84{
85 WCHAR *minVersion, *maxVersion, *p;
87 DWORD time;
88
89 TRACE("package %p, sig %p\n", package, sig);
90
91 memset(sig, 0, sizeof(*sig));
92 sig->Name = name;
93 row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `Signature` WHERE `Signature` = '%s'", name );
94 if (!row)
95 {
96 TRACE("failed to query signature for %s\n", debugstr_w(name));
97 return ERROR_SUCCESS;
98 }
99
100 /* get properties */
101 sig->File = msi_dup_record_field(row,2);
102 if ((p = wcschr(sig->File, '|')))
103 {
104 p++;
105 memmove(sig->File, p, (lstrlenW(p) + 1) * sizeof(WCHAR));
106 }
107
108 minVersion = msi_dup_record_field(row,3);
109 if (minVersion)
110 {
111 msi_parse_version_string( minVersion, &sig->MinVersionMS, &sig->MinVersionLS );
112 free( minVersion );
113 }
114 maxVersion = msi_dup_record_field(row,4);
115 if (maxVersion)
116 {
117 msi_parse_version_string( maxVersion, &sig->MaxVersionMS, &sig->MaxVersionLS );
118 free( maxVersion );
119 }
121 if (sig->MinSize == MSI_NULL_INTEGER)
122 sig->MinSize = 0;
124 if (sig->MaxSize == MSI_NULL_INTEGER)
125 sig->MaxSize = 0;
128 if (time != MSI_NULL_INTEGER)
131 if (time != MSI_NULL_INTEGER)
133
134 TRACE("Found file name %s for Signature_ %s;\n",
136 TRACE("MinVersion is %d.%d.%d.%d\n", HIWORD(sig->MinVersionMS),
138 LOWORD(sig->MinVersionLS));
139 TRACE("MaxVersion is %d.%d.%d.%d\n", HIWORD(sig->MaxVersionMS),
141 LOWORD(sig->MaxVersionLS));
142 TRACE("MinSize is %lu, MaxSize is %lu\n", sig->MinSize, sig->MaxSize);
143 TRACE("Languages is %s\n", debugstr_w(sig->Languages));
144
145 msiobj_release( &row->hdr );
146
147 return ERROR_SUCCESS;
148}
void msi_parse_version_string(LPCWSTR verStr, PDWORD ms, PDWORD ls)
Definition: appsearch.c:52
BOOL WINAPI DosDateTimeToFileTime(IN WORD wFatDate, IN WORD wFatTime, OUT LPFILETIME lpFileTime)
Definition: time.c:75
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
GLfloat GLfloat p
Definition: glext.h:8902
__u16 time
Definition: mkdosfs.c:8
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
int MSI_RecordGetInteger(MSIRECORD *, UINT)
Definition: record.c:213
WCHAR * msi_dup_record_field(MSIRECORD *row, INT index) __WINE_DEALLOC(free) __WINE_MALLOC
Definition: record.c:1002
MSIRECORD *WINAPIV MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR query,...)
Definition: msiquery.c:201
#define MSI_NULL_INTEGER
Definition: msiquery.h:32
#define memset(x, y, z)
Definition: compat.h:39
Definition: name.c:39
LPCWSTR Name
Definition: appsearch.c:39

Referenced by search_sig_name().

◆ is_full_path()

static BOOL is_full_path ( const WCHAR *  path)
static

Definition at line 860 of file appsearch.c.

861{
862 WCHAR first = towupper(path[0]);
863 BOOL ret;
864
865 if (first >= 'A' && first <= 'Z' && path[1] == ':')
866 ret = TRUE;
867 else if (path[0] == '\\' && path[1] == '\\')
868 ret = TRUE;
869 else
870 ret = FALSE;
871 return ret;
872}
return ret
Definition: mutex.c:147
unsigned int BOOL
Definition: ntddk_ex.h:94
const GLint * first
Definition: glext.h:5794
#define towupper(c)
Definition: wctype.h:99

Referenced by search_directory().

◆ ITERATE_AppSearch()

static UINT ITERATE_AppSearch ( MSIRECORD *  row,
LPVOID  param 
)
static

Definition at line 1086 of file appsearch.c.

1087{
1088 MSIPACKAGE *package = param;
1089 LPCWSTR propName, sigName;
1090 LPWSTR value = NULL;
1091 struct signature sig;
1092 MSIRECORD *uirow;
1093 UINT r;
1094
1095 /* get property and signature */
1096 propName = MSI_RecordGetString(row, 1);
1097 sigName = MSI_RecordGetString(row, 2);
1098
1099 TRACE("%s %s\n", debugstr_w(propName), debugstr_w(sigName));
1100
1101 if ((r = load_all_drlocators( package ))) return r;
1102
1103 r = search_sig_name( package, sigName, &sig, &value );
1104 if (value)
1105 {
1106 r = msi_set_property( package->db, propName, value, -1 );
1107 if (r == ERROR_SUCCESS && !wcscmp( propName, L"SourceDir" ))
1108 msi_reset_source_folders( package );
1109
1110 free(value);
1111 }
1112 free_signature( &sig );
1113
1114 uirow = MSI_CreateRecord( 2 );
1115 MSI_RecordSetStringW( uirow, 1, propName );
1116 MSI_RecordSetStringW( uirow, 2, sigName );
1118 msiobj_release( &uirow->hdr );
1119
1120 free_drlocators( package );
1121 return r;
1122}
static UINT search_sig_name(MSIPACKAGE *, const WCHAR *, struct signature *, WCHAR **)
Definition: appsearch.c:1063
static void free_drlocators(MSIPACKAGE *package)
Definition: appsearch.c:979
static UINT load_all_drlocators(MSIPACKAGE *package)
Definition: appsearch.c:963
static void free_signature(struct d3dcompiler_shader_signature *sig)
Definition: reflection.c:270
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
@ INSTALLMESSAGE_ACTIONDATA
Definition: msi.h:103
void msi_reset_source_folders(MSIPACKAGE *package)
Definition: package.c:2121
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT)
Definition: record.c:433
UINT msi_set_property(MSIDATABASE *, const WCHAR *, const WCHAR *, int)
Definition: package.c:2132
INT MSI_ProcessMessage(MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD *)
Definition: package.c:1941
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR)
Definition: record.c:597
MSIRECORD * MSI_CreateRecord(UINT)
Definition: record.c:76

Referenced by ACTION_AppSearch().

◆ ITERATE_CCPSearch()

static UINT ITERATE_CCPSearch ( MSIRECORD *  row,
LPVOID  param 
)
static

Definition at line 1146 of file appsearch.c.

1147{
1148 MSIPACKAGE *package = param;
1150 LPWSTR value = NULL;
1151 struct signature sig;
1153
1155
1156 TRACE("%s\n", debugstr_w(signature));
1157
1158 if ((r = load_all_drlocators( package ))) return r;
1159
1160 search_sig_name( package, signature, &sig, &value );
1161 if (value)
1162 {
1163 TRACE("Found signature %s\n", debugstr_w(signature));
1164 msi_set_property( package->db, L"CCP_Success", L"1", -1 );
1165 free(value);
1167 }
1168
1169 free_signature(&sig);
1170 free_drlocators( package );
1171 return r;
1172}
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105

Referenced by ACTION_CCPSearch().

◆ load_all_drlocators()

static UINT load_all_drlocators ( MSIPACKAGE *  package)
static

Definition at line 963 of file appsearch.c.

964{
965 MSIQUERY *view;
966 UINT r;
967
968 if (!list_empty( &package->drlocators )) return ERROR_SUCCESS;
969
970 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `DrLocator`", &view );
971 if (r != ERROR_SUCCESS)
972 return ERROR_SUCCESS;
973
975 msiobj_release( &view->hdr );
976 return r;
977}
static UINT load_drlocator(MSIRECORD *row, void *param)
Definition: appsearch.c:943
static int list_empty(struct list_entry *head)
Definition: list.h:58
UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY **)

Referenced by ITERATE_AppSearch(), and ITERATE_CCPSearch().

◆ load_drlocator()

static UINT load_drlocator ( MSIRECORD *  row,
void *  param 
)
static

Definition at line 943 of file appsearch.c.

944{
945 MSIPACKAGE *package = param;
947
948 if (!(locator = calloc( 1, sizeof(MSIDRLOCATOR) ))) return ERROR_FUNCTION_FAILED;
949
950 locator->Signature = msi_dup_record_field( row, 1 );
951
952 TRACE("Loading DrLocator %s\n", debugstr_w(locator->Signature));
953
954 locator->Parent = msi_dup_record_field( row, 2 );
955 locator->Path = msi_dup_record_field( row, 3 );
956 locator->Depth = MSI_RecordGetInteger( row, 4 );
957 if (locator->Depth == MSI_NULL_INTEGER) locator->Depth = 0;
958
959 list_add_tail( &package->drlocators, &locator->entry );
960 return ERROR_SUCCESS;
961}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define calloc
Definition: rosglue.h:14
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:1333

Referenced by load_all_drlocators().

◆ match_languages()

static BOOL match_languages ( const void *  version,
const WCHAR *  languages 
)
static

Definition at line 619 of file appsearch.c.

620{
621 struct lang
622 {
623 USHORT id;
625 } *lang;
626 UINT len, j;
627 DWORD num_ids, i;
628 BOOL found = FALSE;
629 LANGID *ids;
630
631 if (!languages || !languages[0]) return TRUE;
632 if (!VerQueryValueW( version, L"\\VarFileInfo\\Translation", (void **)&lang, &len )) return FALSE;
633 if (!(ids = parse_languages( languages, &num_ids ))) return FALSE;
634
635 for (i = 0; i < num_ids; i++)
636 {
637 found = FALSE;
638 for (j = 0; j < len / sizeof(struct lang); j++)
639 {
640 if (!ids[i] || ids[i] == lang[j].id) found = TRUE;
641 }
642 if (!found) goto done;
643 }
644
645done:
646 free( ids );
647 return found;
648}
static LANGID * parse_languages(const WCHAR *languages, DWORD *num_ids)
Definition: appsearch.c:590
GLuint * ids
Definition: glext.h:5907
GLuint id
Definition: glext.h:5910
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 GLint GLint j
Definition: glfuncs.h:250
USHORT LANGID
Definition: mui.h:9
unsigned short USHORT
Definition: pedump.c:61
static const WCHAR lang[]
Definition: wbemdisp.c:287
int codepage
Definition: win_iconv.c:156

Referenced by file_version_matches().

◆ msi_parse_version_string()

void msi_parse_version_string ( LPCWSTR  verStr,
PDWORD  ms,
PDWORD  ls 
)

Definition at line 52 of file appsearch.c.

53{
54 const WCHAR *ptr;
55 int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
56
57 x1 = wcstol(verStr, NULL, 10);
58 ptr = wcschr(verStr, '.');
59 if (ptr)
60 {
61 x2 = wcstol(ptr + 1, NULL, 10);
62 ptr = wcschr(ptr + 1, '.');
63 }
64 if (ptr)
65 {
66 x3 = wcstol(ptr + 1, NULL, 10);
67 ptr = wcschr(ptr + 1, '.');
68 }
69 if (ptr)
70 x4 = wcstol(ptr + 1, NULL, 10);
71 /* FIXME: byte-order dependent? */
72 *ms = x1 << 16 | x2;
73 if (ls) *ls = x3 << 16 | x4;
74}
void ls(int argc, const char *argv[])
Definition: cmds.c:1136
_ACRTIMP __msvcrt_long __cdecl wcstol(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2752
static float int float int float int x3
Definition: server.c:79
static float int float int float int float int x4
Definition: server.c:79
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710

Referenced by check_transform_applicable(), get_signature(), msi_compare_file_versions(), and msi_compare_font_versions().

◆ parse_languages()

static LANGID * parse_languages ( const WCHAR *  languages,
DWORD *  num_ids 
)
static

Definition at line 590 of file appsearch.c.

591{
592 UINT i, count = 1;
593 WCHAR *str = wcsdup( languages ), *p, *q;
594 LANGID *ret;
595
596 if (!str) return NULL;
597 for (p = q = str; (q = wcschr( q, ',' )); q++) count++;
598
599 if (!(ret = malloc( count * sizeof(LANGID) )))
600 {
601 free( str );
602 return NULL;
603 }
604 i = 0;
605 while (*p)
606 {
607 q = wcschr( p, ',' );
608 if (q) *q = 0;
609 ret[i] = wcstol( p, NULL, 10 );
610 if (!q) break;
611 p = q + 1;
612 i++;
613 }
614 free( str );
615 *num_ids = count;
616 return ret;
617}
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
const WCHAR * str

Referenced by match_languages().

◆ recurse_search_directory()

static UINT recurse_search_directory ( MSIPACKAGE *  package,
WCHAR **  appValue,
struct signature *  sig,
const WCHAR *  dir,
int  depth 
)
static

Definition at line 760 of file appsearch.c.

762{
763 HANDLE hFind;
764 WIN32_FIND_DATAW findData;
765 UINT rc = ERROR_SUCCESS;
766 size_t dirLen = lstrlenW(dir), fileLen = lstrlenW(sig->File);
767 WCHAR subpath[MAX_PATH];
768 WCHAR *buf;
769 DWORD len;
770
771 TRACE("Searching directory %s for file %s, depth %d\n", debugstr_w(dir), debugstr_w(sig->File), depth);
772
773 if (depth < 0)
774 return ERROR_SUCCESS;
775
776 *appValue = NULL;
777 /* We need the buffer in both paths below, so go ahead and allocate it
778 * here. Add two because we might need to add a backslash if the dir name
779 * isn't backslash-terminated.
780 */
781 len = dirLen + max(fileLen, lstrlenW(L"*.*")) + 2;
782 buf = malloc(len * sizeof(WCHAR));
783 if (!buf)
784 return ERROR_OUTOFMEMORY;
785
786 lstrcpyW(buf, dir);
788 lstrcatW(buf, sig->File);
789
790 hFind = msi_find_first_file( package, buf, &findData );
791 if (hFind != INVALID_HANDLE_VALUE)
792 {
794 {
796
797 rc = file_matches_sig( package, sig, &findData, buf, &matches );
798 if (rc == ERROR_SUCCESS && matches)
799 {
800 TRACE("found file, returning %s\n", debugstr_w(buf));
801 *appValue = buf;
802 }
803 }
804 FindClose(hFind);
805 }
806
807 if (rc == ERROR_SUCCESS && !*appValue)
808 {
809 lstrcpyW(buf, dir);
811 lstrcatW(buf, L"*.*");
812
813 hFind = msi_find_first_file( package, buf, &findData );
814 if (hFind != INVALID_HANDLE_VALUE)
815 {
817 wcscmp( findData.cFileName, L"." ) &&
818 wcscmp( findData.cFileName, L".." ))
819 {
820 lstrcpyW(subpath, dir);
821 PathAppendW(subpath, findData.cFileName);
822 rc = recurse_search_directory( package, appValue, sig, subpath, depth - 1 );
823 }
824
825 while (rc == ERROR_SUCCESS && !*appValue && msi_find_next_file( package, hFind, &findData ))
826 {
827 if (!wcscmp( findData.cFileName, L"." ) ||
828 !wcscmp( findData.cFileName, L".." ))
829 continue;
830
831 lstrcpyW(subpath, dir);
832 PathAppendW(subpath, findData.cFileName);
834 rc = recurse_search_directory( package, appValue, sig, subpath, depth - 1 );
835 }
836
837 FindClose(hFind);
838 }
839 }
840
841 if (*appValue != buf)
842 free(buf);
843
844 return rc;
845}
static UINT file_matches_sig(MSIPACKAGE *package, const struct signature *sig, const WIN32_FIND_DATAW *findData, const WCHAR *fullFilePath, BOOL *matches)
Definition: appsearch.c:715
static UINT recurse_search_directory(MSIPACKAGE *package, WCHAR **appValue, struct signature *sig, const WCHAR *dir, int depth)
Definition: appsearch.c:760
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
HANDLE msi_find_first_file(MSIPACKAGE *package, const WCHAR *filename, WIN32_FIND_DATAW *data)
Definition: files.c:124
BOOL msi_find_next_file(MSIPACKAGE *package, HANDLE handle, WIN32_FIND_DATAW *data)
Definition: files.c:133
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define PathAddBackslashW
Definition: pathcch.h:302
#define PathAppendW
Definition: pathcch.h:310
_Field_z_ WCHAR cFileName[MAX_PATH]
Definition: minwinbase.h:291
DWORD dwFileAttributes
Definition: minwinbase.h:283
#define max(a, b)
Definition: svc.c:63

Referenced by recurse_search_directory(), and search_directory().

◆ search_components()

static UINT search_components ( MSIPACKAGE *  package,
WCHAR **  appValue,
struct signature *  sig 
)
static

Definition at line 223 of file appsearch.c.

224{
225 MSIRECORD *row, *rec;
227 BOOL sigpresent = TRUE;
228 BOOL isdir;
229 UINT type;
232 LPWSTR ptr;
233 DWORD attr;
234
235 TRACE("%s\n", debugstr_w(sig->Name));
236
237 *appValue = NULL;
238
239 row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `CompLocator` WHERE `Signature_` = '%s'", sig->Name);
240 if (!row)
241 {
242 TRACE("failed to query CompLocator for %s\n", debugstr_w(sig->Name));
243 return ERROR_SUCCESS;
244 }
245
249
250 rec = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Signature` WHERE `Signature` = '%s'", signature);
251 if (!rec)
252 sigpresent = FALSE;
253
254 *path = '\0';
256 if (!*path)
257 goto done;
258
259 attr = msi_get_file_attributes( package, path );
261 goto done;
262
263 isdir = (attr & FILE_ATTRIBUTE_DIRECTORY);
264
265 if (type != msidbLocatorTypeDirectory && sigpresent && !isdir)
266 {
267 *appValue = search_file( package, path, sig );
268 }
269 else if (!sigpresent && (type != msidbLocatorTypeDirectory || isdir))
270 {
272 {
273 ptr = wcsrchr(path, '\\');
274 *(ptr + 1) = '\0';
275 }
276 else
278
279 *appValue = wcsdup(path);
280 }
281 else if (sigpresent)
282 {
285
286 attr = msi_get_file_attributes( package, path );
288 *appValue = wcsdup(path);
289 }
290
291done:
292 if (rec) msiobj_release(&rec->hdr);
293 msiobj_release(&row->hdr);
294 return ERROR_SUCCESS;
295}
static WCHAR * search_file(MSIPACKAGE *package, WCHAR *path, struct signature *sig)
Definition: appsearch.c:157
#define wcsrchr
Definition: compat.h:16
GUID guid
Definition: version.c:147
INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf, LPDWORD pcchBuf)
Definition: msi.c:2435
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
@ msidbLocatorTypeDirectory
Definition: msidefs.h:187
@ msidbLocatorTypeFileName
Definition: msidefs.h:188
MSIOBJECTHDR hdr
Definition: msipriv.h:151

Referenced by search_sig_name().

◆ search_directory()

static UINT search_directory ( MSIPACKAGE *  package,
struct signature *  sig,
const WCHAR *  path,
int  depth,
WCHAR **  appValue 
)
static

Definition at line 874 of file appsearch.c.

875{
876 UINT rc;
877 DWORD attr;
878 WCHAR *val = NULL, *new_val;
879
880 TRACE("%p, %p, %s, %d, %p\n", package, sig, debugstr_w(path), depth, appValue);
881
882 if (is_full_path( path ))
883 {
884 if (sig->File)
885 rc = recurse_search_directory( package, &val, sig, path, depth );
886 else
887 {
888 /* Recursively searching a directory makes no sense when the
889 * directory to search is the thing you're trying to find.
890 */
891 rc = check_directory( package, path, &val );
892 }
893 }
894 else
895 {
896 WCHAR pathWithDrive[MAX_PATH] = { 'C',':','\\',0 };
897 DWORD drives = GetLogicalDrives();
898 int i;
899
900 rc = ERROR_SUCCESS;
901 for (i = 0; rc == ERROR_SUCCESS && !val && i < 26; i++)
902 {
903 if (!(drives & (1 << i)))
904 continue;
905
906 pathWithDrive[0] = 'A' + i;
907 if (GetDriveTypeW(pathWithDrive) != DRIVE_FIXED)
908 continue;
909
910 lstrcpynW(pathWithDrive + 3, path, ARRAY_SIZE(pathWithDrive) - 3);
911
912 if (sig->File)
913 rc = recurse_search_directory( package, &val, sig, pathWithDrive, depth );
914 else
915 rc = check_directory( package, pathWithDrive, &val );
916 }
917 }
918
919 attr = msi_get_file_attributes( package, val );
921 val && val[lstrlenW(val) - 1] != '\\')
922 {
923 new_val = realloc(val, (wcslen(val) + 2) * sizeof(WCHAR));
924 if (!new_val)
925 {
926 free(val);
927 val = NULL;
929 }
930 else
931 {
932 val = new_val;
934 }
935 }
936
937 *appValue = val;
938
939 TRACE("returning %d\n", rc);
940 return rc;
941}
static UINT check_directory(MSIPACKAGE *package, const WCHAR *dir, WCHAR **appValue)
Definition: appsearch.c:847
static BOOL is_full_path(const WCHAR *path)
Definition: appsearch.c:860
#define ARRAY_SIZE(A)
Definition: main.h:20
#define realloc
Definition: debug_ros.c:6
#define lstrcpynW
Definition: compat.h:738
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
DWORD WINAPI DECLSPEC_HOTPATCH GetLogicalDrives(void)
Definition: volume.c:513
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
GLuint GLfloat * val
Definition: glext.h:7180
#define DRIVE_FIXED
Definition: winbase.h:277

Referenced by search_dr(), search_ini(), and search_reg().

◆ search_dr()

static UINT search_dr ( MSIPACKAGE *  package,
WCHAR **  app_value,
struct signature *  sig 
)
static

Definition at line 997 of file appsearch.c.

998{
999 WCHAR path[MAX_PATH], expanded[MAX_PATH], *parent = NULL;
1001 DWORD attr;
1002 UINT rc = ERROR_SUCCESS;
1003
1004 TRACE("%s\n", debugstr_w(sig->Name));
1005
1006 *app_value = NULL;
1007
1009 {
1010 if (!wcscmp( sig->Name, locator->Signature )) break;
1011 }
1012
1013 if (!locator)
1014 {
1015 TRACE("failed to find DrLocator for %s\n", debugstr_w(sig->Name));
1016 goto done;
1017 }
1018 if (locator->Seen)
1019 {
1020 TRACE("DrLocator %s already seen\n", debugstr_w(sig->Name));
1021 goto done;
1022 }
1023 locator->Seen = TRUE;
1024
1025 if (locator->Parent)
1026 {
1027 struct signature parent_sig;
1028
1029 search_sig_name( package, locator->Parent, &parent_sig, &parent );
1030 free_signature( &parent_sig );
1031 if (!parent) return ERROR_SUCCESS;
1032 }
1033
1034 if (locator->Path)
1035 expand_any_path( package, locator->Path, expanded, MAX_PATH );
1036 else
1037 expanded[0] = 0;
1038
1039 if (parent)
1040 {
1041 attr = msi_get_file_attributes( package, parent );
1043 {
1046 }
1047
1048 wcscpy( path, parent );
1049 wcscat( path, expanded );
1050 }
1051 else wcscpy( path, expanded );
1052
1054
1055 rc = search_directory( package, sig, path, locator->Depth, app_value );
1056
1057done:
1058 free( parent );
1059 TRACE("returning %u\n", rc);
1060 return rc;
1061}
static void free_signature(struct signature *sig)
Definition: appsearch.c:151
static UINT search_directory(MSIPACKAGE *, struct signature *, const WCHAR *, int, WCHAR **)
Definition: appsearch.c:874
static void expand_any_path(MSIPACKAGE *package, WCHAR *src, WCHAR *dst, size_t len)
Definition: appsearch.c:560
BOOL WINAPI PathRemoveFileSpecW(WCHAR *path)
Definition: path.c:1121
r parent
Definition: btrfs.c:3010
wcscat
wcscpy
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236

Referenced by search_sig_name().

◆ search_file()

static WCHAR * search_file ( MSIPACKAGE *  package,
WCHAR *  path,
struct signature *  sig 
)
static

Definition at line 157 of file appsearch.c.

158{
160 DWORD attr;
161 UINT size;
162 LPWSTR val = NULL;
164
165 if (!sig->File)
166 {
169
170 attr = msi_get_file_attributes( package, path );
172 return wcsdup(path);
173
174 return NULL;
175 }
176
177 attr = msi_get_file_attributes( package, path );
179 return NULL;
180
181 size = msi_get_file_version_info( package, path, 0, NULL );
182 if (!size)
183 return wcsdup(path);
184
185 buffer = malloc(size);
186 if (!buffer)
187 return NULL;
188
190 if (!size)
191 goto done;
192
193 if (!VerQueryValueW(buffer, L"\\", (LPVOID)&info, &size) || !info)
194 goto done;
195
196 if (sig->MinVersionLS || sig->MinVersionMS)
197 {
198 if (info->dwFileVersionMS < sig->MinVersionMS)
199 goto done;
200
201 if (info->dwFileVersionMS == sig->MinVersionMS &&
202 info->dwFileVersionLS < sig->MinVersionLS)
203 goto done;
204 }
205
206 if (sig->MaxVersionLS || sig->MaxVersionMS)
207 {
208 if (info->dwFileVersionMS > sig->MaxVersionMS)
209 goto done;
210
211 if (info->dwFileVersionMS == sig->MaxVersionMS &&
212 info->dwFileVersionLS > sig->MaxVersionLS)
213 goto done;
214 }
215
216 val = wcsdup(path);
217
218done:
219 free(buffer);
220 return val;
221}
GLuint buffer
Definition: glext.h:5915
unsigned char * LPBYTE
Definition: typedefs.h:53

Referenced by search_components(), search_ini(), and search_reg().

◆ search_ini()

static UINT search_ini ( MSIPACKAGE *  package,
WCHAR **  appValue,
struct signature *  sig 
)
static

Definition at line 497 of file appsearch.c.

498{
499 MSIRECORD *row;
500 LPWSTR fileName, section, key;
501 int field, type;
503
504 TRACE("%s\n", debugstr_w(sig->Name));
505
506 *appValue = NULL;
507
508 row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `IniLocator` WHERE `Signature_` = '%s'", sig->Name );
509 if (!row)
510 {
511 TRACE("failed to query IniLocator for %s\n", debugstr_w(sig->Name));
512 return ERROR_SUCCESS;
513 }
514
515 fileName = msi_dup_record_field(row, 2);
520 if (field == MSI_NULL_INTEGER)
521 field = 0;
522 if (type == MSI_NULL_INTEGER)
523 type = 0;
524
526 if (buf[0])
527 {
528 switch (type & 0x0f)
529 {
531 search_directory( package, sig, buf, 0, appValue );
532 break;
534 *appValue = search_file( package, buf, sig );
535 break;
537 *appValue = get_ini_field(buf, field);
538 break;
539 }
540 }
541
542 free(fileName);
543 free(section);
544 free(key);
545
546 msiobj_release(&row->hdr);
547
548 return ERROR_SUCCESS;
549}
static LPWSTR get_ini_field(LPWSTR buf, int field)
Definition: appsearch.c:471
INT WINAPI GetPrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR def_val, LPWSTR buffer, UINT len, LPCWSTR filename)
Definition: profile.c:1142
@ msidbLocatorTypeRawValue
Definition: msidefs.h:189
Definition: copy.c:22
Definition: parser.c:56

Referenced by search_sig_name().

◆ search_reg()

static UINT search_reg ( MSIPACKAGE *  package,
WCHAR **  appValue,
struct signature *  sig 
)
static

Definition at line 346 of file appsearch.c.

347{
348 const WCHAR *keyPath, *valueName;
349 WCHAR *deformatted = NULL, *ptr = NULL, *end;
350 int root, type;
352 HKEY rootKey, key = NULL;
353 DWORD sz = 0, regType;
354 LPBYTE value = NULL;
355 MSIRECORD *row;
356 UINT rc;
357
358 TRACE("%s\n", debugstr_w(sig->Name));
359
360 *appValue = NULL;
361
362 row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `RegLocator` WHERE `Signature_` = '%s'", sig->Name );
363 if (!row)
364 {
365 TRACE("failed to query RegLocator for %s\n", debugstr_w(sig->Name));
366 return ERROR_SUCCESS;
367 }
368
370 keyPath = MSI_RecordGetString(row, 3);
371 valueName = MSI_RecordGetString(row, 4);
373
374 deformat_string(package, keyPath, &deformatted);
375
376 switch (root)
377 {
379 rootKey = HKEY_CLASSES_ROOT;
380 break;
382 rootKey = HKEY_CURRENT_USER;
383 break;
385 rootKey = HKEY_LOCAL_MACHINE;
387 else access |= KEY_WOW64_32KEY;
388 break;
390 rootKey = HKEY_USERS;
391 break;
392 default:
393 WARN("Unknown root key %d\n", root);
394 goto end;
395 }
396
397 rc = RegOpenKeyExW( rootKey, deformatted, 0, access, &key );
398 if (rc)
399 {
400 TRACE("RegOpenKeyExW returned %d\n", rc);
401 goto end;
402 }
403
404 free(deformatted);
405 deformat_string(package, valueName, &deformatted);
406
407 rc = RegQueryValueExW(key, deformatted, NULL, NULL, NULL, &sz);
408 if (rc)
409 {
410 TRACE("RegQueryValueExW returned %d\n", rc);
411 goto end;
412 }
413 /* FIXME: sanity-check sz before allocating (is there an upper-limit
414 * on the value of a property?)
415 */
416 value = malloc(sz);
417 rc = RegQueryValueExW(key, deformatted, NULL, &regType, value, &sz);
418 if (rc)
419 {
420 TRACE("RegQueryValueExW returned %d\n", rc);
421 goto end;
422 }
423
424 /* bail out if the registry key is empty */
425 if (sz == 0)
426 goto end;
427
428 /* expand if needed */
429 if (regType == REG_EXPAND_SZ)
430 {
432 if (sz)
433 {
434 WCHAR *buf = malloc(sz * sizeof(WCHAR));
436 free(value);
437 value = (LPBYTE)buf;
438 }
439 }
440
441 if ((regType == REG_SZ || regType == REG_EXPAND_SZ) &&
442 (ptr = wcschr((LPWSTR)value, '"')) && (end = wcschr(++ptr, '"')))
443 *end = '\0';
444 else
445 ptr = (LPWSTR)value;
446
447 switch (type & 0x0f)
448 {
450 search_directory( package, sig, ptr, 0, appValue );
451 break;
453 *appValue = search_file( package, ptr, sig );
454 break;
456 convert_reg_value( regType, value, sz, appValue );
457 break;
458 default:
459 FIXME("unimplemented for type %d (key path %s, value %s)\n",
460 type, debugstr_w(keyPath), debugstr_w(valueName));
461 }
462end:
463 free( value );
464 RegCloseKey( key );
465 free( deformatted );
466
467 msiobj_release(&row->hdr);
468 return ERROR_SUCCESS;
469}
static void convert_reg_value(DWORD regType, const BYTE *value, DWORD sz, WCHAR **appValue)
Definition: appsearch.c:297
#define FIXME(fmt,...)
Definition: precomp.h:53
#define RegCloseKey(hKey)
Definition: registry.h:49
struct _root root
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
@ msidbLocatorType64bit
Definition: msidefs.h:190
@ msidbRegistryRootClassesRoot
Definition: msidefs.h:179
@ msidbRegistryRootUsers
Definition: msidefs.h:182
@ msidbRegistryRootLocalMachine
Definition: msidefs.h:181
@ msidbRegistryRootCurrentUser
Definition: msidefs.h:180
#define KEY_READ
Definition: nt_native.h:1026
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
ACCESS_MASK REGSAM
Definition: winreg.h:76
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define HKEY_USERS
Definition: winreg.h:13
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46

Referenced by search_sig_name().

◆ search_sig_name()

static UINT search_sig_name ( MSIPACKAGE *  package,
const WCHAR *  sigName,
struct signature *  sig,
WCHAR **  appValue 
)
static

Definition at line 1063 of file appsearch.c.

1064{
1065 UINT rc;
1066
1067 *appValue = NULL;
1068 rc = get_signature( package, sig, sigName );
1069 if (rc == ERROR_SUCCESS)
1070 {
1071 rc = search_components( package, appValue, sig );
1072 if (rc == ERROR_SUCCESS && !*appValue)
1073 {
1074 rc = search_reg( package, appValue, sig );
1075 if (rc == ERROR_SUCCESS && !*appValue)
1076 {
1077 rc = search_ini( package, appValue, sig );
1078 if (rc == ERROR_SUCCESS && !*appValue)
1079 rc = search_dr( package, appValue, sig );
1080 }
1081 }
1082 }
1083 return rc;
1084}
static UINT search_reg(MSIPACKAGE *package, WCHAR **appValue, struct signature *sig)
Definition: appsearch.c:346
static UINT search_components(MSIPACKAGE *package, WCHAR **appValue, struct signature *sig)
Definition: appsearch.c:223
static UINT get_signature(MSIPACKAGE *package, struct signature *sig, const WCHAR *name)
Definition: appsearch.c:83
static UINT search_dr(MSIPACKAGE *package, WCHAR **app_value, struct signature *sig)
Definition: appsearch.c:997
static UINT search_ini(MSIPACKAGE *package, WCHAR **appValue, struct signature *sig)
Definition: appsearch.c:497

Referenced by ITERATE_AppSearch(), ITERATE_CCPSearch(), and search_dr().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msi  )