wbemprox: Add a partial implementation of Win32_Directory.
Hans Leidekker
hans at codeweavers.com
Wed May 29 05:16:44 CDT 2013
---
dlls/wbemprox/builtin.c | 256 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 250 insertions(+), 6 deletions(-)
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 2d89281..fc77419 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -51,6 +51,8 @@ static const WCHAR class_cdromdriveW[] =
{'W','i','n','3','2','_','C','D','R','O','M','D','r','i','v','e',0};
static const WCHAR class_compsysW[] =
{'W','i','n','3','2','_','C','o','m','p','u','t','e','r','S','y','s','t','e','m',0};
+static const WCHAR class_directoryW[] =
+ {'W','i','n','3','2','_','D','i','r','e','c','t','o','r','y',0};
static const WCHAR class_diskdriveW[] =
{'W','i','n','3','2','_','D','i','s','k','D','r','i','v','e',0};
static const WCHAR class_diskpartitionW[] =
@@ -77,14 +79,16 @@ static const WCHAR class_sounddeviceW[] =
static const WCHAR class_videocontrollerW[] =
{'W','i','n','3','2','_','V','i','d','e','o','C','o','n','t','r','o','l','l','e','r',0};
-static const WCHAR prop_adaptertypeW[] =
- {'A','d','a','p','t','e','r','T','y','p','e',0};
static const WCHAR prop_acceptpauseW[] =
{'A','c','c','e','p','t','P','a','u','s','e',0};
static const WCHAR prop_acceptstopW[] =
{'A','c','c','e','p','t','S','t','o','p',0};
+static const WCHAR prop_accessmaskW[] =
+ {'A','c','c','e','s','s','M','a','s','k',0};
static const WCHAR prop_adapterramW[] =
{'A','d','a','p','t','e','r','R','A','M',0};
+static const WCHAR prop_adaptertypeW[] =
+ {'A','d','a','p','t','e','r','T','y','p','e',0};
static const WCHAR prop_bootableW[] =
{'B','o','o','t','a','b','l','e',0};
static const WCHAR prop_bootpartitionW[] =
@@ -258,6 +262,11 @@ static const struct column col_compsys[] =
{ prop_numprocessorsW, CIM_UINT32, VT_I4 },
{ prop_totalphysicalmemoryW, CIM_UINT64 }
};
+static const struct column col_directory[] =
+{
+ { prop_accessmaskW, CIM_UINT32 },
+ { prop_nameW, CIM_STRING|COL_FLAG_KEY }
+};
static const struct column col_diskdrive[] =
{
{ prop_deviceidW, CIM_STRING|COL_FLAG_KEY },
@@ -489,6 +498,11 @@ struct record_computersystem
UINT32 num_processors;
UINT64 total_physical_memory;
};
+struct record_directory
+{
+ UINT32 accessmask;
+ const WCHAR *name;
+};
struct record_diskdrive
{
const WCHAR *device_id;
@@ -856,6 +870,238 @@ static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize )
return free.QuadPart;
}
+struct dirstack
+{
+ WCHAR **dirs;
+ UINT *len_dirs;
+ UINT num_dirs;
+ UINT num_allocated;
+};
+
+static struct dirstack *alloc_dirstack( UINT size )
+{
+ struct dirstack *dirstack;
+
+ if (!(dirstack = heap_alloc( sizeof(*dirstack) ))) return NULL;
+ if (!(dirstack->dirs = heap_alloc( sizeof(WCHAR *) * size )))
+ {
+ heap_free( dirstack );
+ return NULL;
+ }
+ if (!(dirstack->len_dirs = heap_alloc( sizeof(UINT) * size )))
+ {
+ heap_free( dirstack->dirs );
+ heap_free( dirstack );
+ return NULL;
+ }
+ dirstack->num_dirs = 0;
+ dirstack->num_allocated = size;
+ return dirstack;
+}
+
+static void free_dirstack( struct dirstack *dirstack )
+{
+ UINT i;
+ for (i = 0; i < dirstack->num_dirs; i++) heap_free( dirstack->dirs[i] );
+ heap_free( dirstack->dirs );
+ heap_free( dirstack->len_dirs );
+ heap_free( dirstack );
+}
+
+static BOOL push_dir( struct dirstack *dirstack, WCHAR *dir, UINT len )
+{
+ UINT size, i = dirstack->num_dirs;
+
+ if (i == dirstack->num_allocated)
+ {
+ WCHAR **tmp;
+ UINT *len_tmp;
+
+ size = dirstack->num_allocated * 2;
+ if (!(tmp = heap_realloc( dirstack->dirs, size * sizeof(WCHAR *) ))) return FALSE;
+ dirstack->dirs = tmp;
+ if (!(len_tmp = heap_realloc( dirstack->len_dirs, size * sizeof(UINT) ))) return FALSE;
+ dirstack->len_dirs = len_tmp;
+ dirstack->num_allocated = size;
+ }
+ dirstack->dirs[i] = dir;
+ dirstack->len_dirs[i] = len;
+ dirstack->num_dirs++;
+ return TRUE;
+}
+
+static WCHAR *pop_dir( struct dirstack *dirstack, UINT *len )
+{
+ if (!dirstack->num_dirs)
+ {
+ *len = 0;
+ return NULL;
+ }
+ dirstack->num_dirs--;
+ *len = dirstack->len_dirs[dirstack->num_dirs];
+ return dirstack->dirs[dirstack->num_dirs];
+}
+
+static const WCHAR *peek_dir( struct dirstack *dirstack )
+{
+ if (!dirstack->num_dirs) return NULL;
+ return dirstack->dirs[dirstack->num_dirs - 1];
+}
+
+static WCHAR *build_glob( WCHAR drive, const WCHAR *path, UINT len )
+{
+ UINT i = 0;
+ WCHAR *ret;
+
+ if (!(ret = heap_alloc( (len + 6) * sizeof(WCHAR) ))) return NULL;
+ ret[i++] = drive;
+ ret[i++] = ':';
+ ret[i++] = '\\';
+ if (path)
+ {
+ memcpy( ret + i, path, len * sizeof(WCHAR) );
+ i += len;
+ ret[i++] = '\\';
+ }
+ ret[i++] = '*';
+ ret[i] = 0;
+ return ret;
+}
+
+static WCHAR *build_dirname( WCHAR drive, const WCHAR *path )
+{
+ UINT i = 0, len = 0;
+ const WCHAR *p;
+ WCHAR *ret;
+
+ for (p = path; *p; p++)
+ {
+ if (*p == '\\') len += 2;
+ else len++;
+ };
+ if (!(ret = heap_alloc( (len + 5) * sizeof(WCHAR) ))) return NULL;
+ ret[i++] = drive;
+ ret[i++] = ':';
+ ret[i++] = '\\';
+ ret[i++] = '\\';
+ for (p = path; *p; p++)
+ {
+ if (*p != '\\') ret[i++] = *p;
+ else
+ {
+ ret[i++] = '\\';
+ ret[i++] = '\\';
+ }
+ }
+ ret[i] = 0;
+ return ret;
+}
+
+static WCHAR *append_path( const WCHAR *path, const WCHAR *segment, UINT *len )
+{
+ UINT len_path = 0, len_segment = strlenW( segment );
+ WCHAR *ret;
+
+ *len = 0;
+ if (path) len_path = strlenW( path );
+ if (!(ret = heap_alloc( (len_path + len_segment + 2) * sizeof(WCHAR) ))) return NULL;
+ if (path)
+ {
+ memcpy( ret, path, len_path * sizeof(WCHAR) );
+ ret[len_path] = '\\';
+ *len += len_path + 1;
+ }
+ memcpy( ret + *len, segment, len_segment * sizeof(WCHAR) );
+ *len += len_segment;
+ ret[*len] = 0;
+ return ret;
+}
+
+static enum fill_status fill_directory( struct table *table, const struct expr *cond )
+{
+ static const WCHAR dotW[] = {'.',0}, dotdotW[] = {'.','.',0};
+ struct record_directory *rec;
+ UINT i, len, row = 0, offset = 0, count = 4;
+ WCHAR *glob = NULL, *path = NULL, *new_path, root[] = {'A',':','\\',0};
+ DWORD drives = GetLogicalDrives();
+ WIN32_FIND_DATAW data;
+ HANDLE handle;
+ struct dirstack *dirstack = alloc_dirstack(2);
+ enum fill_status status = FILL_STATUS_UNFILTERED;
+
+ if (!(table->data = heap_alloc( count * sizeof(*rec) ))) return FILL_STATUS_FAILED;
+
+ for (i = 0; i < sizeof(drives); i++)
+ {
+ if (!(drives & (1 << i))) continue;
+
+ root[0] = 'A' + i;
+ if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
+
+ for (;;)
+ {
+ path = pop_dir( dirstack, &len );
+ if (!(glob = build_glob( root[0], path, len )))
+ {
+ status = FILL_STATUS_FAILED;
+ goto done;
+ }
+ if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (row > count)
+ {
+ BYTE *data;
+ count *= 2;
+ if (!(data = heap_realloc( table->data, count * sizeof(*rec) )))
+ {
+ status = FILL_STATUS_FAILED;
+ goto done;
+ }
+ table->data = data;
+ }
+ if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
+ !strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW ))
+ continue;
+
+ new_path = append_path( path, data.cFileName, &len );
+ if (!(push_dir( dirstack, new_path, len )))
+ {
+ heap_free( new_path );
+ status = FILL_STATUS_FAILED;
+ goto done;
+ }
+ rec = (struct record_directory *)(table->data + offset);
+ rec->accessmask = FILE_ALL_ACCESS;
+ rec->name = build_dirname( root[0], new_path );
+ if (!match_row( table, row, cond, &status ))
+ {
+ free_row_values( table, row );
+ continue;
+ }
+ offset += sizeof(*rec);
+ row++;
+ }
+ while (FindNextFileW( handle, &data ));
+ FindClose( handle );
+ }
+ if (!peek_dir( dirstack )) break;
+ heap_free( glob );
+ heap_free( path );
+ }
+ }
+
+done:
+ free_dirstack( dirstack );
+ heap_free( glob );
+ heap_free( path );
+
+ TRACE("created %u rows\n", row);
+ table->num_rows = row;
+ return status;
+}
+
static enum fill_status fill_diskpartition( struct table *table, const struct expr *cond )
{
static const WCHAR fmtW[] =
@@ -1143,10 +1389,7 @@ static void regs_to_str( unsigned int *regs, unsigned int len, WCHAR *buffer )
unsigned int i;
unsigned char *p = (unsigned char *)regs;
- for (i = 0; i < len; i++)
- {
- buffer[i] = *p++;
- }
+ for (i = 0; i < len; i++) { buffer[i] = *p++; }
buffer[i] = 0;
}
static void get_processor_manufacturer( WCHAR *manufacturer )
@@ -1532,6 +1775,7 @@ static struct table builtin_classes[] =
{ class_biosW, SIZEOF(col_bios), col_bios, SIZEOF(data_bios), (BYTE *)data_bios },
{ class_cdromdriveW, SIZEOF(col_cdromdrive), col_cdromdrive, 0, NULL, fill_cdromdrive },
{ class_compsysW, SIZEOF(col_compsys), col_compsys, 0, NULL, fill_compsys },
+ { class_directoryW, SIZEOF(col_directory), col_directory, 0, NULL, fill_directory },
{ class_diskdriveW, SIZEOF(col_diskdrive), col_diskdrive, SIZEOF(data_diskdrive), (BYTE *)data_diskdrive },
{ class_diskpartitionW, SIZEOF(col_diskpartition), col_diskpartition, 0, NULL, fill_diskpartition },
{ class_logicaldiskW, SIZEOF(col_logicaldisk), col_logicaldisk, 0, NULL, fill_logicaldisk },
--
1.7.10.4
More information about the wine-patches
mailing list