diff --git a/.gitignore b/.gitignore
index c67db7b..63a76db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -140,6 +140,7 @@ stamp-h[1-9]
/src/serpentcrypt
/src/unicodetouch
/src/wevtinfo
+/src/wpsname
/src/winregsave
/src/winshellfolder
/src/winshelllink
diff --git a/autogen.ps1 b/autogen.ps1
index fd3f68b..5a75d5e 100644
--- a/autogen.ps1
+++ b/autogen.ps1
@@ -9,13 +9,7 @@ $Library = Get-Content -Path configure.ac | select -skip 3 -first 1 | % { $_ -Re
$Version = Get-Content -Path configure.ac | select -skip 4 -first 1 | % { $_ -Replace " \[","" } | % { $_ -Replace "\],","" }
$Prefix = ${Library}.Substring(3)
-Get-Content -Path "include\${Library}.h.in" | Out-File -Encoding ascii "include\${Library}.h"
-Get-Content -Path "include\${Library}\definitions.h.in" | % { $_ -Replace "@VERSION@","${Version}" } | Out-File -Encoding ascii "include\${Library}\definitions.h"
-Get-Content -Path "include\${Library}\features.h.in" | % { $_ -Replace "@[A-Z0-9_]*@","0" } | Out-File -Encoding ascii "include\${Library}\features.h"
-Get-Content -Path "include\${Library}\types.h.in" | % { $_ -Replace "@[A-Z0-9_]*@","0" } | Out-File -Encoding ascii "include\${Library}\types.h"
Get-Content -Path "common\types.h.in" | % { $_ -Replace "@PACKAGE@","${Library}" } | Out-File -Encoding ascii "common\types.h"
-Get-Content -Path "${Library}\${Library}_definitions.h.in" | % { $_ -Replace "@VERSION@","${Version}" } | Out-File -Encoding ascii "${Library}\${Library}_definitions.h"
-Get-Content -Path "${Library}\${Library}.rc.in" | % { $_ -Replace "@VERSION@","${Version}" } | Out-File -Encoding ascii "${Library}\${Library}.rc"
If (Test-Path "setup.cfg.in")
{
@@ -27,38 +21,3 @@ If (Test-Path "${Prefix}.net")
Get-Content -Path "${Prefix}.net\${Prefix}.net.rc.in" | % { $_ -Replace "@VERSION@","${Version}" } | Out-File -Encoding ascii "${Prefix}.net\${Prefix}.net.rc"
}
-$NamePrefix = ""
-
-ForEach (${Library} in Get-ChildItem -Directory -Path "lib*")
-{
- ForEach (${DirectoryElement} in Get-ChildItem -Path "${Library}\*.l")
- {
- $OutputFile = ${DirectoryElement} -Replace ".l$",".c"
-
- $NamePrefix = Split-Path -path ${DirectoryElement} -leaf
- $NamePrefix = ${NamePrefix} -Replace ".l$","_"
-
- Write-Host "Running: ${WinFlex} -Cf ${DirectoryElement}"
-
- # PowerShell will raise NativeCommandError if win_flex writes to stdout or stderr
- # therefore 2>&1 is added and the output is stored in a variable.
- $Output = Invoke-Expression -Command "& '${WinFlex}' -Cf ${DirectoryElement} 2>&1"
- Write-Host ${Output}
-
- # Moving manually since `win_flex -o filename' does not provide the expected behavior.
- Move-Item "lex.yy.c" ${OutputFile} -force
- }
-
- ForEach (${DirectoryElement} in Get-ChildItem -Path "${Library}\*.y")
- {
- $OutputFile = ${DirectoryElement} -Replace ".y$",".c"
-
- Write-Host "Running: ${WinBison} -d -v -l -p ${NamePrefix} -o ${OutputFile} ${DirectoryElement}"
-
- # PowerShell will raise NativeCommandError if win_bison writes to stdout or stderr
- # therefore 2>&1 is added and the output is stored in a variable.
- $Output = Invoke-Expression -Command "& '${WinBison}' -d -v -l -p ${NamePrefix} -o ${OutputFile} ${DirectoryElement} 2>&1"
- Write-Host ${Output}
- }
-}
-
diff --git a/msvscpp/Makefile.am b/msvscpp/Makefile.am
index 968f2f4..e7f1cc0 100644
--- a/msvscpp/Makefile.am
+++ b/msvscpp/Makefile.am
@@ -55,6 +55,7 @@ MSVSCPP_FILES = \
winregsave/winregsave.vcproj \
winshellfolder/winshellfolder.vcproj \
winshelllink/winshelllink.vcproj \
+ wpsname/wpsname.vcproj \
xor32sum/xor32sum.vcproj \
xor64sum/xor64sum.vcproj \
zcompress/zcompress.vcproj \
diff --git a/msvscpp/assorted.sln b/msvscpp/assorted.sln
index b2bb7c7..d667b38 100644
--- a/msvscpp/assorted.sln
+++ b/msvscpp/assorted.sln
@@ -221,6 +221,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wevtinfo", "wevtinfo\wevtin
{DD4C0210-D36E-4E74-AA91-B39E54E81E22} = {DD4C0210-D36E-4E74-AA91-B39E54E81E22}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wpsname", "wpsname\wpsname.vcproj", "{703A8EDC-5601-4662-A226-1C4FFBFEB6C3}"
+ ProjectSection(ProjectDependencies) = postProject
+ {16510E82-C099-4A58-8ABE-E62D36E945E8} = {16510E82-C099-4A58-8ABE-E62D36E945E8}
+ {7CCEB0A1-5BFC-4006-A364-EDAFC545EBF3} = {7CCEB0A1-5BFC-4006-A364-EDAFC545EBF3}
+ {2B851ED2-22C8-4BB6-AE22-E49A75536FF5} = {2B851ED2-22C8-4BB6-AE22-E49A75536FF5}
+ {12DF7DB4-FC19-44F7-89B6-B7221EA77BE6} = {12DF7DB4-FC19-44F7-89B6-B7221EA77BE6}
+ {952218B5-15F2-4EEC-B67D-164407BAE738} = {952218B5-15F2-4EEC-B67D-164407BAE738}
+ {DD4C0210-D36E-4E74-AA91-B39E54E81E22} = {DD4C0210-D36E-4E74-AA91-B39E54E81E22}
+ EndProjectSection
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winregsave", "winregsave\winregsave.vcproj", "{9A2ECE73-F064-437E-A379-D4DE6A040116}"
ProjectSection(ProjectDependencies) = postProject
{7CCEB0A1-5BFC-4006-A364-EDAFC545EBF3} = {7CCEB0A1-5BFC-4006-A364-EDAFC545EBF3}
@@ -574,6 +584,10 @@ Global
{4600994E-D3A1-43F0-BCEE-A4AA7C7781C8}.Release|Win32.Build.0 = Release|Win32
{4600994E-D3A1-43F0-BCEE-A4AA7C7781C8}.VSDebug|Win32.ActiveCfg = VSDebug|Win32
{4600994E-D3A1-43F0-BCEE-A4AA7C7781C8}.VSDebug|Win32.Build.0 = VSDebug|Win32
+ {703A8EDC-5601-4662-A226-1C4FFBFEB6C3}.Release|Win32.ActiveCfg = Release|Win32
+ {703A8EDC-5601-4662-A226-1C4FFBFEB6C3}.Release|Win32.Build.0 = Release|Win32
+ {703A8EDC-5601-4662-A226-1C4FFBFEB6C3}.VSDebug|Win32.ActiveCfg = VSDebug|Win32
+ {703A8EDC-5601-4662-A226-1C4FFBFEB6C3}.VSDebug|Win32.Build.0 = VSDebug|Win32
{9A2ECE73-F064-437E-A379-D4DE6A040116}.Release|Win32.ActiveCfg = Release|Win32
{9A2ECE73-F064-437E-A379-D4DE6A040116}.Release|Win32.Build.0 = Release|Win32
{9A2ECE73-F064-437E-A379-D4DE6A040116}.VSDebug|Win32.ActiveCfg = VSDebug|Win32
diff --git a/msvscpp/wpsname/wpsname.vcproj b/msvscpp/wpsname/wpsname.vcproj
new file mode 100644
index 0000000..321084b
--- /dev/null
+++ b/msvscpp/wpsname/wpsname.vcproj
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Makefile.am b/src/Makefile.am
index 83a8915..ab0ef13 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -48,6 +48,7 @@ bin_PROGRAMS = \
serpentcrypt \
unicodetouch \
wevtinfo \
+ wpsname \
winregsave \
winshellfolder \
winshelllink \
@@ -478,6 +479,24 @@ wevtinfo_LDADD = \
@LIBCDATA_LIBADD@ \
@LIBCERROR_LIBADD@
+wpsname_SOURCES = \
+ assorted_getopt.c assorted_getopt.h \
+ assorted_i18n.h \
+ assorted_libcerror.h \
+ assorted_libcfile.h \
+ assorted_libcnotify.h \
+ assorted_libfguid.h \
+ assorted_output.c assorted_output.h \
+ wpsname.c
+
+wpsname_LDADD = \
+ @LIBFGUID_LIBADD@ \
+ @LIBCFILE_LIBADD@ \
+ @LIBUNA_LIBADD@ \
+ @LIBCNOTIFY_LIBADD@ \
+ @LIBCLOCALE_LIBADD@ \
+ @LIBCERROR_LIBADD@
+
winregsave_SOURCES = \
assorted_getopt.c assorted_getopt.h \
assorted_i18n.h \
diff --git a/src/assorted_libfguid.h b/src/assorted_libfguid.h
new file mode 100644
index 0000000..6723cea
--- /dev/null
+++ b/src/assorted_libfguid.h
@@ -0,0 +1,49 @@
+/*
+ * The libfguid header wrapper
+ *
+ * Copyright (C) 2008-2024, Joachim Metz
+ *
+ * Refer to AUTHORS for acknowledgements.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+#if !defined( _ASSORTED_LIBFGUID_H )
+#define _ASSORTED_LIBFGUID_H
+
+#include
+
+/* Define HAVE_LOCAL_LIBFGUID for local use of libfguid
+ */
+#if defined( HAVE_LOCAL_LIBFGUID )
+
+#include
+#include
+#include
+
+#else
+
+/* If libtool DLL support is enabled set LIBFGUID_DLL_IMPORT
+ * before including libfguid.h
+ */
+#if defined( _WIN32 ) && defined( DLL_IMPORT ) && !defined( HAVE_STATIC_EXECUTABLES )
+#define LIBFGUID_DLL_IMPORT
+#endif
+
+#include
+
+#endif /* defined( HAVE_LOCAL_LIBFGUID ) */
+
+#endif /* !defined( _ASSORTED_LIBFGUID_H ) */
+
diff --git a/src/winshellfolder.c b/src/winshellfolder.c
index e0d107e..4260a5a 100644
--- a/src/winshellfolder.c
+++ b/src/winshellfolder.c
@@ -54,7 +54,7 @@ void usage_fprint(
}
fprintf( stream, "Use winshellfolder to determine a Shell Folder from a path.\n\n" );
- fprintf( stream, "Usage: winshellfolder [ -12hvV ] path\n\n" );
+ fprintf( stream, "Usage: winshellfolder [ -hvV ] path\n\n" );
fprintf( stream, "\tpath: the path to determine the shell folder of.\n" );
diff --git a/src/winshelllink.c b/src/winshelllink.c
index 3e999e4..f71790f 100644
--- a/src/winshelllink.c
+++ b/src/winshelllink.c
@@ -55,7 +55,7 @@ void usage_fprint(
}
fprintf( stream, "Use winshelllink to determine a Shell Link from a path.\n\n" );
- fprintf( stream, "Usage: winshelllink [ -12hvV ] path\n\n" );
+ fprintf( stream, "Usage: winshelllink [ -hvV ] path\n\n" );
fprintf( stream, "\tpath: the path to determine the shell link of.\n" );
diff --git a/src/wpsname.c b/src/wpsname.c
new file mode 100644
index 0000000..bc937d2
--- /dev/null
+++ b/src/wpsname.c
@@ -0,0 +1,293 @@
+/*
+ * Determines the name of a Windows Property Store (WPS) property key
+ *
+ * Copyright (C) 2008-2024, Joachim Metz
+ *
+ * Refer to AUTHORS for acknowledgements.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#if defined( HAVE_STDLIB_H )
+#include
+#endif
+
+#if defined( WINAPI )
+#include
+#include
+#endif
+
+#include "assorted_getopt.h"
+#include "assorted_libcerror.h"
+#include "assorted_libcfile.h"
+#include "assorted_libcnotify.h"
+#include "assorted_libfguid.h"
+#include "assorted_output.h"
+
+/* Prints the executable usage information
+ */
+void usage_fprint(
+ FILE *stream )
+{
+ if( stream == NULL )
+ {
+ return;
+ }
+ fprintf( stream, "Use wpsname to determine the name of a Windows Property Store\n"
+ " (WPS) property key.\n\n" );
+
+ fprintf( stream, "Usage: wpsname [ -hvV ] guid pid\n\n" );
+
+ fprintf( stream, "\tguid: format identifier.\n" );
+ fprintf( stream, "\tpid: property identifier.\n" );
+
+ fprintf( stream, "\t-h: shows this help\n" );
+ fprintf( stream, "\t-v: verbose output to stderr\n" );
+ fprintf( stream, "\t-V: print version\n" );
+ fprintf( stream, "\n" );
+}
+
+/* The main program
+ */
+#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
+int wmain( int argc, wchar_t * const argv[] )
+#else
+int main( int argc, char * const argv[] )
+#endif
+{
+ libcerror_error_t *error = NULL;
+ system_character_t *options_string = NULL;
+ system_character_t *format_identifier = NULL;
+ system_character_t *property_identifier = NULL;
+ char *program = "wpsname";
+ system_integer_t option = 0;
+ size_t string_length = 0;
+ int verbose = 0;
+
+#if defined( WINAPI )
+ PROPERTYKEY property_key;
+
+ wchar_t *name = NULL;
+ HRESULT result = 0;
+#endif
+
+ assorted_output_version_fprint(
+ stdout,
+ program );
+
+ options_string = _SYSTEM_STRING( "hvV" );
+
+ while( ( option = assorted_getopt(
+ argc,
+ argv,
+ options_string ) ) != (system_integer_t) -1 )
+ {
+ switch( option )
+ {
+ case (system_integer_t) '?':
+ default:
+ fprintf(
+ stderr,
+ "Invalid argument: %" PRIs_SYSTEM "\n",
+ argv[ optind ] );
+
+ usage_fprint(
+ stdout );
+
+ return( EXIT_FAILURE );
+
+ case (system_integer_t) 'h':
+ usage_fprint(
+ stdout );
+
+ return( EXIT_SUCCESS );
+
+ case (system_integer_t) 'v':
+ verbose = 1;
+
+ break;
+
+ case (system_integer_t) 'V':
+ assorted_output_copyright_fprint(
+ stdout );
+
+ return( EXIT_SUCCESS );
+ }
+ }
+ if( optind == argc )
+ {
+ fprintf(
+ stderr,
+ "Missing format identifier (GUID).\n" );
+
+ usage_fprint(
+ stdout );
+
+ return( EXIT_FAILURE );
+ }
+ format_identifier = argv[ optind++ ];
+
+ if( optind == argc )
+ {
+ fprintf(
+ stderr,
+ "Missing property identifier (PID).\n" );
+
+ usage_fprint(
+ stdout );
+
+ return( EXIT_FAILURE );
+ }
+ property_identifier = argv[ optind++ ];
+
+ libcnotify_stream_set(
+ stderr,
+ NULL );
+ libcnotify_verbose_set(
+ verbose );
+
+#if defined( WINAPI )
+ string_length = system_string_length(
+ format_identifier );
+
+ if( libfguid_identifier_initialize(
+ &guid,
+ error ) != 1 )
+ {
+ libcerror_error_set(
+ error,
+ LIBCERROR_ERROR_DOMAIN_RUNTIME,
+ LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
+ "%s: unable to create GUID.",
+ function );
+
+ goto on_error;
+ }
+ if( libfguid_identifier_copy_from_utf8_string(
+ guid,
+ format_identifier,
+ string_length,
+ LIBFGUID_STRING_FORMAT_FLAG_USE_MIXED_CASE,
+ error ) != 1 )
+ {
+ libcerror_error_set(
+ error,
+ LIBCERROR_ERROR_DOMAIN_RUNTIME,
+ LIBCERROR_RUNTIME_ERROR_SET_FAILED,
+ "%s: unable to copy GUID from string.",
+ function );
+
+ goto on_error;
+ }
+ if( libfguid_identifier_copy_to_byte_stream(
+ guid,
+ property_key.fmtid,
+ 16,
+ LIBFGUID_ENDIAN_LITTLE,
+ error ) != 1 )
+ {
+ libcerror_error_set(
+ error,
+ LIBCERROR_ERROR_DOMAIN_RUNTIME,
+ LIBCERROR_RUNTIME_ERROR_SET_FAILED,
+ "%s: unable to copy GUID to byte stream.",
+ function );
+
+ goto on_error;
+ }
+ if( libfguid_identifier_free(
+ &guid,
+ error ) != 1 )
+ {
+ libcerror_error_set(
+ error,
+ LIBCERROR_ERROR_DOMAIN_RUNTIME,
+ LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
+ "%s: unable to free GUID.",
+ function );
+
+ goto on_error;
+ }
+
+ result = CoInitialize(
+ NULL );
+
+ if( FAILED( result ) )
+ {
+ result = GetLastError();
+
+ libcerror_system_set_error(
+ &error,
+ LIBCERROR_ERROR_DOMAIN_RUNTIME,
+ LIBCERROR_RUNTIME_ERROR_GENERIC,
+ (uint32_t) result,
+ "unable to initialize COM." );
+
+ goto on_error;
+ }
+ property_key.pid = atol( property_identifier );
+
+ result = PSGetNameFromPropertyKey(
+ &property_key, &name );
+
+ if( SUCCEEDED( result ) )
+ {
+ fprintf( stdout, "%ls\n", name );
+
+ CoTaskMemFree( name );
+ }
+ CoUninitialize();
+
+ return( EXIT_SUCCESS );
+#else
+ fprintf(
+ stderr,
+ "This program requires WINAPI.\n" );
+
+ return( EXIT_FAILURE );
+
+#endif /* defined( WINAPI ) */
+
+on_error:
+ if( error != NULL )
+ {
+ libcnotify_print_error_backtrace(
+ error );
+ libcerror_error_free(
+ &error );
+ }
+#if defined( WINAPI )
+ if( persist_file != NULL )
+ {
+ persist_file->lpVtbl->Release(
+ persist_file );
+ }
+ if( shell_link != NULL )
+ {
+ shell_link->lpVtbl->Release(
+ shell_link );
+ }
+ CoUninitialize();
+
+#endif /* defined( WINAPI ) */
+
+ return( EXIT_FAILURE );
+}
+