├── .gitignore ├── COM └── linkom_atl │ ├── Linkom.rgs │ ├── LinkomCoClass.cpp │ ├── LinkomCoClass.h │ ├── dlldata.c │ ├── dllmain.cpp │ ├── dllmain.h │ ├── linkom_atl.cpp │ ├── linkom_atl.def │ ├── linkom_atl.idl │ ├── linkom_atl.rc │ ├── linkom_atl.rgs │ ├── linkom_atl.sln │ ├── linkom_atl.vcxproj │ ├── linkom_atl.vcxproj.filters │ ├── linkom_atlPS.vcxproj │ ├── linkom_atlPS.vcxproj.filters │ ├── linkom_atl_i.c │ ├── linkom_atl_i.h │ ├── linkom_atl_p.c │ ├── linkom_atlps.def │ ├── resource.h │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h ├── LICENSE ├── linkom.h ├── readme.md ├── samples ├── c │ └── emulfake.c └── cs │ └── EmulFakeCS │ ├── EmulFakeCS.csproj │ ├── EmulFakeCS.sln │ ├── Program.cs │ └── Properties │ └── AssemblyInfo.cs ├── testrun.c └── vs2015 ├── emulfake.vcxproj ├── emulfake.vcxproj.filters ├── linkom_vs.sln ├── testrun.vcxproj └── testrun.vcxproj.filters /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | *.su 34 | -------------------------------------------------------------------------------- /COM/linkom_atl/Linkom.rgs: -------------------------------------------------------------------------------- 1 | HKCR 2 | { 3 | Linkom.1.1 = s 'Linkom Class' 4 | { 5 | CLSID = s '{AB8BC6BA-2478-4849-B4B3-058D4EDE3660}' 6 | } 7 | Linkom.1 = s 'Linkom Class' 8 | { 9 | CurVer = s 'Linkom.Component.1' 10 | } 11 | NoRemove CLSID 12 | { 13 | ForceRemove {AB8BC6BA-2478-4849-B4B3-058D4EDE3660} = s 'Linkom Class' 14 | { 15 | ProgID = s 'Linkom.Component.1' 16 | VersionIndependentProgID = s 'Linkom.1' 17 | InprocServer32 = s '%MODULE%' 18 | { 19 | } 20 | TypeLib = s '{C61FE5D4-6F4E-4693-A707-3AB2B1DD4F89}' 21 | Version = s '1.0' 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /COM/linkom_atl/LinkomCoClass.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hernandp/linkom/53609c48d4813e957ab31b42de53f85c29c45bcc/COM/linkom_atl/LinkomCoClass.cpp -------------------------------------------------------------------------------- /COM/linkom_atl/LinkomCoClass.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hernandp/linkom/53609c48d4813e957ab31b42de53f85c29c45bcc/COM/linkom_atl/LinkomCoClass.h -------------------------------------------------------------------------------- /COM/linkom_atl/dlldata.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | DllData file -- generated by MIDL compiler 3 | 4 | DO NOT ALTER THIS FILE 5 | 6 | This file is regenerated by MIDL on every IDL file compile. 7 | 8 | To completely reconstruct this file, delete it and rerun MIDL 9 | on all the IDL files in this DLL, specifying this file for the 10 | /dlldata command line option 11 | 12 | *********************************************************/ 13 | 14 | #define PROXY_DELEGATION 15 | 16 | #include 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | EXTERN_PROXY_FILE( linkom_atl ) 23 | 24 | 25 | PROXYFILE_LIST_START 26 | /* Start of list */ 27 | REFERENCE_PROXY_FILE( linkom_atl ), 28 | /* End of list */ 29 | PROXYFILE_LIST_END 30 | 31 | 32 | DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID ) 33 | 34 | #ifdef __cplusplus 35 | } /*extern "C" */ 36 | #endif 37 | 38 | /* end of generated dlldata file */ 39 | -------------------------------------------------------------------------------- /COM/linkom_atl/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Implementation of DllMain. 2 | 3 | #include "stdafx.h" 4 | #include "resource.h" 5 | #include "linkom_atl_i.h" 6 | #include "dllmain.h" 7 | 8 | Clinkom_atlModule _AtlModule; 9 | 10 | // DLL Entry Point 11 | extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) 12 | { 13 | hInstance; 14 | return _AtlModule.DllMain(dwReason, lpReserved); 15 | } 16 | -------------------------------------------------------------------------------- /COM/linkom_atl/dllmain.h: -------------------------------------------------------------------------------- 1 | // dllmain.h : Declaration of module class. 2 | 3 | class Clinkom_atlModule : public ATL::CAtlDllModuleT< Clinkom_atlModule > 4 | { 5 | public : 6 | DECLARE_LIBID(LIBID_Linkom) 7 | DECLARE_REGISTRY_APPID_RESOURCEID(IDR_LINKOM_ATL, "{9804386C-C343-4919-9714-70EAF0406C30}") 8 | }; 9 | 10 | extern class Clinkom_atlModule _AtlModule; 11 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atl.cpp: -------------------------------------------------------------------------------- 1 | // linkom_atl.cpp : Implementation of DLL Exports. 2 | 3 | 4 | #include "stdafx.h" 5 | #include "resource.h" 6 | #include "linkom_atl_i.h" 7 | #include "dllmain.h" 8 | 9 | 10 | using namespace ATL; 11 | 12 | // Used to determine whether the DLL can be unloaded by OLE. 13 | STDAPI DllCanUnloadNow(void) 14 | { 15 | return _AtlModule.DllCanUnloadNow(); 16 | } 17 | 18 | // Returns a class factory to create an object of the requested type. 19 | _Check_return_ 20 | STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID* ppv) 21 | { 22 | return _AtlModule.DllGetClassObject(rclsid, riid, ppv); 23 | } 24 | 25 | // DllRegisterServer - Adds entries to the system registry. 26 | STDAPI DllRegisterServer(void) 27 | { 28 | // registers object, typelib and all interfaces in typelib 29 | HRESULT hr = _AtlModule.DllRegisterServer(); 30 | return hr; 31 | } 32 | 33 | // DllUnregisterServer - Removes entries from the system registry. 34 | STDAPI DllUnregisterServer(void) 35 | { 36 | HRESULT hr = _AtlModule.DllUnregisterServer(); 37 | return hr; 38 | } 39 | 40 | // DllInstall - Adds/Removes entries to the system registry per user per machine. 41 | STDAPI DllInstall(BOOL bInstall, _In_opt_ LPCWSTR pszCmdLine) 42 | { 43 | HRESULT hr = E_FAIL; 44 | static const wchar_t szUserSwitch[] = L"user"; 45 | 46 | if (pszCmdLine != NULL) 47 | { 48 | if (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0) 49 | { 50 | ATL::AtlSetPerUserRegistration(true); 51 | } 52 | } 53 | 54 | if (bInstall) 55 | { 56 | hr = DllRegisterServer(); 57 | if (FAILED(hr)) 58 | { 59 | DllUnregisterServer(); 60 | } 61 | } 62 | else 63 | { 64 | hr = DllUnregisterServer(); 65 | } 66 | 67 | return hr; 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atl.def: -------------------------------------------------------------------------------- 1 | ; linkom_atl.def : Declares the module parameters. 2 | 3 | LIBRARY 4 | 5 | EXPORTS 6 | DllCanUnloadNow PRIVATE 7 | DllGetClassObject PRIVATE 8 | DllRegisterServer PRIVATE 9 | DllUnregisterServer PRIVATE 10 | DllInstall PRIVATE 11 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atl.idl: -------------------------------------------------------------------------------- 1 | import "oaidl.idl"; 2 | import "ocidl.idl"; 3 | 4 | [ 5 | object, 6 | uuid(601BF357-E6D9-4E3E-8DEC-908E559A9D69), 7 | oleautomation, 8 | nonextensible, 9 | pointer_default(unique) 10 | ] 11 | interface ILinkom : IUnknown{ 12 | 13 | [helpstring("Sets a syntax specification for the parser to work with.")] 14 | HRESULT SetSyntax([in] BSTR syntaxSpec, [out] BSTR* invalidToken, [out, retval] unsigned long* reasonCode); 15 | 16 | [helpstring("Parse a commandline string")] 17 | HRESULT Parse([in] BSTR commandLine, [out] BSTR* invalidArg, [out, retval] unsigned long* reasonCode); 18 | 19 | [helpstring("Returns boolean TRUE if this parameter is present")] 20 | HRESULT IsParamPresent([in] BSTR paramName, [out, retval] BOOL* bPresent); 21 | 22 | [helpstring("Returns a parameter value, if present")] 23 | HRESULT GetParamValue([in] BSTR paramName, [out] BSTR* paramValue, [out, retval] unsigned long* reasonCode); 24 | 25 | [helpstring("Gets the extended error string for the last Parse or SetSyntax operation call.")] 26 | HRESULT GetExtErrorString([out, retval] BSTR* errString); 27 | 28 | }; 29 | [ 30 | uuid(C61FE5D4-6F4E-4693-A707-3AB2B1DD4F89), 31 | version(1.0) 32 | ] 33 | library Linkom 34 | { 35 | importlib("stdole2.tlb"); 36 | [ 37 | uuid(AB8BC6BA-2478-4849-B4B3-058D4EDE3660) 38 | ] 39 | coclass Linkom 40 | { 41 | [default] interface ILinkom; 42 | }; 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atl.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hernandp/linkom/53609c48d4813e957ab31b42de53f85c29c45bcc/COM/linkom_atl/linkom_atl.rc -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atl.rgs: -------------------------------------------------------------------------------- 1 | HKCR 2 | { 3 | } 4 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atl.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "linkom_atl", "linkom_atl.vcxproj", "{A5E44802-66F3-4BC6-B7CB-E768BF1352EE}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "linkom_atlPS", "linkom_atlPS.vcxproj", "{29C1FBA6-F1B1-43CD-A219-DCB24852BE54}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {A5E44802-66F3-4BC6-B7CB-E768BF1352EE} = {A5E44802-66F3-4BC6-B7CB-E768BF1352EE} 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|x64 = Release|x64 18 | Release|x86 = Release|x86 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {A5E44802-66F3-4BC6-B7CB-E768BF1352EE}.Debug|x64.ActiveCfg = Debug|x64 22 | {A5E44802-66F3-4BC6-B7CB-E768BF1352EE}.Debug|x64.Build.0 = Debug|x64 23 | {A5E44802-66F3-4BC6-B7CB-E768BF1352EE}.Debug|x86.ActiveCfg = Debug|Win32 24 | {A5E44802-66F3-4BC6-B7CB-E768BF1352EE}.Debug|x86.Build.0 = Debug|Win32 25 | {A5E44802-66F3-4BC6-B7CB-E768BF1352EE}.Release|x64.ActiveCfg = Release|x64 26 | {A5E44802-66F3-4BC6-B7CB-E768BF1352EE}.Release|x64.Build.0 = Release|x64 27 | {A5E44802-66F3-4BC6-B7CB-E768BF1352EE}.Release|x86.ActiveCfg = Release|Win32 28 | {A5E44802-66F3-4BC6-B7CB-E768BF1352EE}.Release|x86.Build.0 = Release|Win32 29 | {29C1FBA6-F1B1-43CD-A219-DCB24852BE54}.Debug|x64.ActiveCfg = Debug|x64 30 | {29C1FBA6-F1B1-43CD-A219-DCB24852BE54}.Debug|x86.ActiveCfg = Debug|Win32 31 | {29C1FBA6-F1B1-43CD-A219-DCB24852BE54}.Release|x64.ActiveCfg = Release|x64 32 | {29C1FBA6-F1B1-43CD-A219-DCB24852BE54}.Release|x86.ActiveCfg = Release|Win32 33 | EndGlobalSection 34 | GlobalSection(SolutionProperties) = preSolution 35 | HideSolutionNode = FALSE 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atl.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {A5E44802-66F3-4BC6-B7CB-E768BF1352EE} 23 | 8.1 24 | AtlProj 25 | 26 | 27 | 28 | DynamicLibrary 29 | true 30 | v140 31 | Unicode 32 | 33 | 34 | DynamicLibrary 35 | false 36 | v140 37 | Unicode 38 | 39 | 40 | DynamicLibrary 41 | true 42 | v140 43 | Unicode 44 | 45 | 46 | DynamicLibrary 47 | false 48 | v140 49 | Unicode 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | true 71 | true 72 | 73 | 74 | true 75 | true 76 | 77 | 78 | true 79 | false 80 | 81 | 82 | true 83 | false 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions) 91 | true 92 | 93 | 94 | false 95 | Win32 96 | _DEBUG;%(PreprocessorDefinitions) 97 | linkom_atl_i.h 98 | linkom_atl_i.c 99 | linkom_atl_p.c 100 | true 101 | $(IntDir)linkom_atl.tlb 102 | 103 | true 104 | 105 | 106 | 0x0409 107 | $(IntDir);%(AdditionalIncludeDirectories) 108 | _DEBUG;%(PreprocessorDefinitions) 109 | 110 | 111 | Windows 112 | .\linkom_atl.def 113 | true 114 | true 115 | 116 | 117 | 118 | 119 | Use 120 | Level3 121 | Disabled 122 | _WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions) 123 | true 124 | 125 | 126 | false 127 | _DEBUG;%(PreprocessorDefinitions) 128 | linkom_atl_i.h 129 | linkom_atl_i.c 130 | linkom_atl_p.c 131 | true 132 | $(IntDir)linkom_atl.tlb 133 | 134 | true 135 | 136 | 137 | 0x0409 138 | $(IntDir);%(AdditionalIncludeDirectories) 139 | _DEBUG;%(PreprocessorDefinitions) 140 | 141 | 142 | Windows 143 | .\linkom_atl.def 144 | true 145 | true 146 | 147 | 148 | 149 | 150 | Use 151 | Level3 152 | MaxSpeed 153 | WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions) 154 | true 155 | 156 | 157 | false 158 | Win32 159 | NDEBUG;%(PreprocessorDefinitions) 160 | linkom_atl_i.h 161 | linkom_atl_i.c 162 | linkom_atl_p.c 163 | true 164 | $(IntDir)linkom_atl.tlb 165 | 166 | true 167 | 168 | 169 | 0x0409 170 | $(IntDir);%(AdditionalIncludeDirectories) 171 | NDEBUG;%(PreprocessorDefinitions) 172 | 173 | 174 | Windows 175 | .\linkom_atl.def 176 | true 177 | true 178 | true 179 | true 180 | 181 | 182 | 183 | 184 | Use 185 | Level3 186 | MaxSpeed 187 | _WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions) 188 | true 189 | 190 | 191 | false 192 | NDEBUG;%(PreprocessorDefinitions) 193 | linkom_atl_i.h 194 | linkom_atl_i.c 195 | linkom_atl_p.c 196 | true 197 | $(IntDir)linkom_atl.tlb 198 | 199 | true 200 | 201 | 202 | 0x0409 203 | $(IntDir);%(AdditionalIncludeDirectories) 204 | NDEBUG;%(PreprocessorDefinitions) 205 | 206 | 207 | Windows 208 | .\linkom_atl.def 209 | true 210 | true 211 | true 212 | true 213 | 214 | 215 | 216 | 217 | false 218 | 219 | 220 | false 221 | 222 | 223 | false 224 | 225 | 226 | false 227 | 228 | 229 | 230 | 231 | 232 | 233 | false 234 | 235 | 236 | false 237 | 238 | 239 | false 240 | 241 | 242 | false 243 | 244 | 245 | 246 | 247 | Create 248 | Create 249 | Create 250 | Create 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atl.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {cd201d17-2e3d-4d41-a308-0be6243c100f} 18 | False 19 | 20 | 21 | 22 | 23 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | Generated Files 33 | 34 | 35 | Source Files 36 | 37 | 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Generated Files 53 | 54 | 55 | Header Files 56 | 57 | 58 | 59 | 60 | Resource Files 61 | 62 | 63 | 64 | 65 | Resource Files 66 | 67 | 68 | Source Files 69 | 70 | 71 | Resource Files 72 | 73 | 74 | 75 | 76 | Source Files 77 | 78 | 79 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atlPS.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {29C1FBA6-F1B1-43CD-A219-DCB24852BE54} 23 | AtlPSProj 24 | 25 | 26 | 27 | DynamicLibrary 28 | true 29 | v140 30 | Unicode 31 | 32 | 33 | DynamicLibrary 34 | false 35 | v140 36 | Unicode 37 | 38 | 39 | DynamicLibrary 40 | true 41 | v140 42 | Unicode 43 | 44 | 45 | DynamicLibrary 46 | false 47 | v140 48 | Unicode 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | $(Configuration)PS\ 70 | 71 | 72 | $(Configuration)PS\ 73 | 74 | 75 | $(Configuration)PS\ 76 | 77 | 78 | $(Configuration)PS\ 79 | 80 | 81 | 82 | WIN32;REGISTER_PROXY_DLL;_DEBUG;%(PreprocessorDefinitions) 83 | 84 | 85 | kernel32.lib;rpcns4.lib;rpcrt4.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies) 86 | linkom_atlPS.def 87 | true 88 | 89 | 90 | if exist dlldata.c goto :END 91 | echo Error: MIDL will not generate DLLDATA.C unless you have at least 1 interface in the main project. 92 | Exit 1 93 | :END 94 | 95 | Checking for required files 96 | 97 | 98 | 99 | 100 | REGISTER_PROXY_DLL;_DEBUG;%(PreprocessorDefinitions) 101 | 102 | 103 | kernel32.lib;rpcns4.lib;rpcrt4.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies) 104 | linkom_atlPS.def 105 | true 106 | 107 | 108 | if exist dlldata.c goto :END 109 | echo Error: MIDL will not generate DLLDATA.C unless you have at least 1 interface in the main project. 110 | Exit 1 111 | :END 112 | 113 | Checking for required files 114 | 115 | 116 | 117 | 118 | MaxSpeed 119 | WIN32;REGISTER_PROXY_DLL;NDEBUG;%(PreprocessorDefinitions) 120 | 121 | 122 | kernel32.lib;rpcns4.lib;rpcrt4.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies) 123 | linkom_atlPS.def 124 | true 125 | true 126 | true 127 | 128 | 129 | if exist dlldata.c goto :END 130 | echo Error: MIDL will not generate DLLDATA.C unless you have at least 1 interface in the main project. 131 | Exit 1 132 | :END 133 | 134 | Checking for required files 135 | 136 | 137 | 138 | 139 | MaxSpeed 140 | REGISTER_PROXY_DLL;NDEBUG;%(PreprocessorDefinitions) 141 | 142 | 143 | kernel32.lib;rpcns4.lib;rpcrt4.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies) 144 | linkom_atlPS.def 145 | true 146 | true 147 | true 148 | 149 | 150 | if exist dlldata.c goto :END 151 | echo Error: MIDL will not generate DLLDATA.C unless you have at least 1 interface in the main project. 152 | Exit 1 153 | :END 154 | 155 | Checking for required files 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atlPS.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {1d44742d-2b2c-40f9-8ac9-f97a5003cd59} 6 | 7 | 8 | {26cd6377-c0e6-4e7d-87d2-3cb25e58794c} 9 | False 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Generated Files 18 | 19 | 20 | Generated Files 21 | 22 | 23 | Generated Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atl_i.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ 4 | 5 | /* link this file in with the server and any clients */ 6 | 7 | 8 | /* File created by MIDL compiler version 8.00.0603 */ 9 | /* at Tue Nov 29 23:54:09 2016 10 | */ 11 | /* Compiler settings for linkom_atl.idl: 12 | Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0603 13 | protocol : dce , ms_ext, c_ext, robust 14 | error checks: allocation ref bounds_check enum stub_data 15 | VC __declspec() decoration level: 16 | __declspec(uuid()), __declspec(selectany), __declspec(novtable) 17 | DECLSPEC_UUID(), MIDL_INTERFACE() 18 | */ 19 | /* @@MIDL_FILE_HEADING( ) */ 20 | 21 | #pragma warning( disable: 4049 ) /* more than 64k source lines */ 22 | 23 | 24 | #ifdef __cplusplus 25 | extern "C"{ 26 | #endif 27 | 28 | 29 | #include 30 | #include 31 | 32 | #ifdef _MIDL_USE_GUIDDEF_ 33 | 34 | #ifndef INITGUID 35 | #define INITGUID 36 | #include 37 | #undef INITGUID 38 | #else 39 | #include 40 | #endif 41 | 42 | #define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ 43 | DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) 44 | 45 | #else // !_MIDL_USE_GUIDDEF_ 46 | 47 | #ifndef __IID_DEFINED__ 48 | #define __IID_DEFINED__ 49 | 50 | typedef struct _IID 51 | { 52 | unsigned long x; 53 | unsigned short s1; 54 | unsigned short s2; 55 | unsigned char c[8]; 56 | } IID; 57 | 58 | #endif // __IID_DEFINED__ 59 | 60 | #ifndef CLSID_DEFINED 61 | #define CLSID_DEFINED 62 | typedef IID CLSID; 63 | #endif // CLSID_DEFINED 64 | 65 | #define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ 66 | const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} 67 | 68 | #endif !_MIDL_USE_GUIDDEF_ 69 | 70 | MIDL_DEFINE_GUID(IID, IID_ILinkom,0x601BF357,0xE6D9,0x4E3E,0x8D,0xEC,0x90,0x8E,0x55,0x9A,0x9D,0x69); 71 | 72 | 73 | MIDL_DEFINE_GUID(IID, LIBID_Linkom,0xC61FE5D4,0x6F4E,0x4693,0xA7,0x07,0x3A,0xB2,0xB1,0xDD,0x4F,0x89); 74 | 75 | 76 | MIDL_DEFINE_GUID(CLSID, CLSID_Linkom,0xAB8BC6BA,0x2478,0x4849,0xB4,0xB3,0x05,0x8D,0x4E,0xDE,0x36,0x60); 77 | 78 | #undef MIDL_DEFINE_GUID 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atl_i.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* this ALWAYS GENERATED file contains the definitions for the interfaces */ 4 | 5 | 6 | /* File created by MIDL compiler version 8.00.0603 */ 7 | /* at Tue Nov 29 23:54:09 2016 8 | */ 9 | /* Compiler settings for linkom_atl.idl: 10 | Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0603 11 | protocol : dce , ms_ext, c_ext, robust 12 | error checks: allocation ref bounds_check enum stub_data 13 | VC __declspec() decoration level: 14 | __declspec(uuid()), __declspec(selectany), __declspec(novtable) 15 | DECLSPEC_UUID(), MIDL_INTERFACE() 16 | */ 17 | /* @@MIDL_FILE_HEADING( ) */ 18 | 19 | #pragma warning( disable: 4049 ) /* more than 64k source lines */ 20 | 21 | 22 | /* verify that the version is high enough to compile this file*/ 23 | #ifndef __REQUIRED_RPCNDR_H_VERSION__ 24 | #define __REQUIRED_RPCNDR_H_VERSION__ 475 25 | #endif 26 | 27 | #include "rpc.h" 28 | #include "rpcndr.h" 29 | 30 | #ifndef __RPCNDR_H_VERSION__ 31 | #error this stub requires an updated version of 32 | #endif // __RPCNDR_H_VERSION__ 33 | 34 | #ifndef COM_NO_WINDOWS_H 35 | #include "windows.h" 36 | #include "ole2.h" 37 | #endif /*COM_NO_WINDOWS_H*/ 38 | 39 | #ifndef __linkom_atl_i_h__ 40 | #define __linkom_atl_i_h__ 41 | 42 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) 43 | #pragma once 44 | #endif 45 | 46 | /* Forward Declarations */ 47 | 48 | #ifndef __ILinkom_FWD_DEFINED__ 49 | #define __ILinkom_FWD_DEFINED__ 50 | typedef interface ILinkom ILinkom; 51 | 52 | #endif /* __ILinkom_FWD_DEFINED__ */ 53 | 54 | 55 | #ifndef __Linkom_FWD_DEFINED__ 56 | #define __Linkom_FWD_DEFINED__ 57 | 58 | #ifdef __cplusplus 59 | typedef class Linkom Linkom; 60 | #else 61 | typedef struct Linkom Linkom; 62 | #endif /* __cplusplus */ 63 | 64 | #endif /* __Linkom_FWD_DEFINED__ */ 65 | 66 | 67 | /* header files for imported files */ 68 | #include "oaidl.h" 69 | #include "ocidl.h" 70 | 71 | #ifdef __cplusplus 72 | extern "C"{ 73 | #endif 74 | 75 | 76 | #ifndef __ILinkom_INTERFACE_DEFINED__ 77 | #define __ILinkom_INTERFACE_DEFINED__ 78 | 79 | /* interface ILinkom */ 80 | /* [unique][nonextensible][oleautomation][uuid][object] */ 81 | 82 | 83 | EXTERN_C const IID IID_ILinkom; 84 | 85 | #if defined(__cplusplus) && !defined(CINTERFACE) 86 | 87 | MIDL_INTERFACE("601BF357-E6D9-4E3E-8DEC-908E559A9D69") 88 | ILinkom : public IUnknown 89 | { 90 | public: 91 | virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetSyntax( 92 | /* [in] */ BSTR syntaxSpec, 93 | /* [out] */ BSTR *invalidToken, 94 | /* [retval][out] */ unsigned long *reasonCode) = 0; 95 | 96 | virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Parse( 97 | /* [in] */ BSTR commandLine, 98 | /* [out] */ BSTR *invalidArg, 99 | /* [retval][out] */ unsigned long *reasonCode) = 0; 100 | 101 | virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE IsParamPresent( 102 | /* [in] */ BSTR paramName, 103 | /* [retval][out] */ BOOL *bPresent) = 0; 104 | 105 | virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetParamValue( 106 | /* [in] */ BSTR paramName, 107 | /* [out] */ BSTR *paramValue, 108 | /* [retval][out] */ unsigned long *reasonCode) = 0; 109 | 110 | virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetExtErrorString( 111 | /* [retval][out] */ BSTR *errString) = 0; 112 | 113 | }; 114 | 115 | 116 | #else /* C style interface */ 117 | 118 | typedef struct ILinkomVtbl 119 | { 120 | BEGIN_INTERFACE 121 | 122 | HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 123 | ILinkom * This, 124 | /* [in] */ REFIID riid, 125 | /* [annotation][iid_is][out] */ 126 | _COM_Outptr_ void **ppvObject); 127 | 128 | ULONG ( STDMETHODCALLTYPE *AddRef )( 129 | ILinkom * This); 130 | 131 | ULONG ( STDMETHODCALLTYPE *Release )( 132 | ILinkom * This); 133 | 134 | /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetSyntax )( 135 | ILinkom * This, 136 | /* [in] */ BSTR syntaxSpec, 137 | /* [out] */ BSTR *invalidToken, 138 | /* [retval][out] */ unsigned long *reasonCode); 139 | 140 | /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Parse )( 141 | ILinkom * This, 142 | /* [in] */ BSTR commandLine, 143 | /* [out] */ BSTR *invalidArg, 144 | /* [retval][out] */ unsigned long *reasonCode); 145 | 146 | /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *IsParamPresent )( 147 | ILinkom * This, 148 | /* [in] */ BSTR paramName, 149 | /* [retval][out] */ BOOL *bPresent); 150 | 151 | /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetParamValue )( 152 | ILinkom * This, 153 | /* [in] */ BSTR paramName, 154 | /* [out] */ BSTR *paramValue, 155 | /* [retval][out] */ unsigned long *reasonCode); 156 | 157 | /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetExtErrorString )( 158 | ILinkom * This, 159 | /* [retval][out] */ BSTR *errString); 160 | 161 | END_INTERFACE 162 | } ILinkomVtbl; 163 | 164 | interface ILinkom 165 | { 166 | CONST_VTBL struct ILinkomVtbl *lpVtbl; 167 | }; 168 | 169 | 170 | 171 | #ifdef COBJMACROS 172 | 173 | 174 | #define ILinkom_QueryInterface(This,riid,ppvObject) \ 175 | ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 176 | 177 | #define ILinkom_AddRef(This) \ 178 | ( (This)->lpVtbl -> AddRef(This) ) 179 | 180 | #define ILinkom_Release(This) \ 181 | ( (This)->lpVtbl -> Release(This) ) 182 | 183 | 184 | #define ILinkom_SetSyntax(This,syntaxSpec,invalidToken,reasonCode) \ 185 | ( (This)->lpVtbl -> SetSyntax(This,syntaxSpec,invalidToken,reasonCode) ) 186 | 187 | #define ILinkom_Parse(This,commandLine,invalidArg,reasonCode) \ 188 | ( (This)->lpVtbl -> Parse(This,commandLine,invalidArg,reasonCode) ) 189 | 190 | #define ILinkom_IsParamPresent(This,paramName,bPresent) \ 191 | ( (This)->lpVtbl -> IsParamPresent(This,paramName,bPresent) ) 192 | 193 | #define ILinkom_GetParamValue(This,paramName,paramValue,reasonCode) \ 194 | ( (This)->lpVtbl -> GetParamValue(This,paramName,paramValue,reasonCode) ) 195 | 196 | #define ILinkom_GetExtErrorString(This,errString) \ 197 | ( (This)->lpVtbl -> GetExtErrorString(This,errString) ) 198 | 199 | #endif /* COBJMACROS */ 200 | 201 | 202 | #endif /* C style interface */ 203 | 204 | 205 | 206 | 207 | #endif /* __ILinkom_INTERFACE_DEFINED__ */ 208 | 209 | 210 | 211 | #ifndef __Linkom_LIBRARY_DEFINED__ 212 | #define __Linkom_LIBRARY_DEFINED__ 213 | 214 | /* library Linkom */ 215 | /* [version][uuid] */ 216 | 217 | 218 | EXTERN_C const IID LIBID_Linkom; 219 | 220 | EXTERN_C const CLSID CLSID_Linkom; 221 | 222 | #ifdef __cplusplus 223 | 224 | class DECLSPEC_UUID("AB8BC6BA-2478-4849-B4B3-058D4EDE3660") 225 | Linkom; 226 | #endif 227 | #endif /* __Linkom_LIBRARY_DEFINED__ */ 228 | 229 | /* Additional Prototypes for ALL interfaces */ 230 | 231 | unsigned long __RPC_USER BSTR_UserSize( unsigned long *, unsigned long , BSTR * ); 232 | unsigned char * __RPC_USER BSTR_UserMarshal( unsigned long *, unsigned char *, BSTR * ); 233 | unsigned char * __RPC_USER BSTR_UserUnmarshal(unsigned long *, unsigned char *, BSTR * ); 234 | void __RPC_USER BSTR_UserFree( unsigned long *, BSTR * ); 235 | 236 | /* end of Additional Prototypes */ 237 | 238 | #ifdef __cplusplus 239 | } 240 | #endif 241 | 242 | #endif 243 | 244 | 245 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atl_p.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* this ALWAYS GENERATED file contains the proxy stub code */ 4 | 5 | 6 | /* File created by MIDL compiler version 8.00.0603 */ 7 | /* at Tue Nov 29 23:54:09 2016 8 | */ 9 | /* Compiler settings for linkom_atl.idl: 10 | Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0603 11 | protocol : dce , ms_ext, c_ext, robust 12 | error checks: allocation ref bounds_check enum stub_data 13 | VC __declspec() decoration level: 14 | __declspec(uuid()), __declspec(selectany), __declspec(novtable) 15 | DECLSPEC_UUID(), MIDL_INTERFACE() 16 | */ 17 | /* @@MIDL_FILE_HEADING( ) */ 18 | 19 | #if defined(_M_AMD64) 20 | 21 | 22 | #pragma warning( disable: 4049 ) /* more than 64k source lines */ 23 | #if _MSC_VER >= 1200 24 | #pragma warning(push) 25 | #endif 26 | 27 | #pragma warning( disable: 4211 ) /* redefine extern to static */ 28 | #pragma warning( disable: 4232 ) /* dllimport identity*/ 29 | #pragma warning( disable: 4024 ) /* array to pointer mapping*/ 30 | #pragma warning( disable: 4152 ) /* function/data pointer conversion in expression */ 31 | 32 | #define USE_STUBLESS_PROXY 33 | 34 | 35 | /* verify that the version is high enough to compile this file*/ 36 | #ifndef __REDQ_RPCPROXY_H_VERSION__ 37 | #define __REQUIRED_RPCPROXY_H_VERSION__ 475 38 | #endif 39 | 40 | 41 | #include "rpcproxy.h" 42 | #ifndef __RPCPROXY_H_VERSION__ 43 | #error this stub requires an updated version of 44 | #endif /* __RPCPROXY_H_VERSION__ */ 45 | 46 | 47 | #include "linkom_atl_i.h" 48 | 49 | #define TYPE_FORMAT_STRING_SIZE 61 50 | #define PROC_FORMAT_STRING_SIZE 233 51 | #define EXPR_FORMAT_STRING_SIZE 1 52 | #define TRANSMIT_AS_TABLE_SIZE 0 53 | #define WIRE_MARSHAL_TABLE_SIZE 1 54 | 55 | typedef struct _linkom_atl_MIDL_TYPE_FORMAT_STRING 56 | { 57 | short Pad; 58 | unsigned char Format[ TYPE_FORMAT_STRING_SIZE ]; 59 | } linkom_atl_MIDL_TYPE_FORMAT_STRING; 60 | 61 | typedef struct _linkom_atl_MIDL_PROC_FORMAT_STRING 62 | { 63 | short Pad; 64 | unsigned char Format[ PROC_FORMAT_STRING_SIZE ]; 65 | } linkom_atl_MIDL_PROC_FORMAT_STRING; 66 | 67 | typedef struct _linkom_atl_MIDL_EXPR_FORMAT_STRING 68 | { 69 | long Pad; 70 | unsigned char Format[ EXPR_FORMAT_STRING_SIZE ]; 71 | } linkom_atl_MIDL_EXPR_FORMAT_STRING; 72 | 73 | 74 | static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax = 75 | {{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}}; 76 | 77 | 78 | extern const linkom_atl_MIDL_TYPE_FORMAT_STRING linkom_atl__MIDL_TypeFormatString; 79 | extern const linkom_atl_MIDL_PROC_FORMAT_STRING linkom_atl__MIDL_ProcFormatString; 80 | extern const linkom_atl_MIDL_EXPR_FORMAT_STRING linkom_atl__MIDL_ExprFormatString; 81 | 82 | 83 | extern const MIDL_STUB_DESC Object_StubDesc; 84 | 85 | 86 | extern const MIDL_SERVER_INFO ILinkom_ServerInfo; 87 | extern const MIDL_STUBLESS_PROXY_INFO ILinkom_ProxyInfo; 88 | 89 | 90 | extern const USER_MARSHAL_ROUTINE_QUADRUPLE UserMarshalRoutines[ WIRE_MARSHAL_TABLE_SIZE ]; 91 | 92 | #if !defined(__RPC_WIN64__) 93 | #error Invalid build platform for this stub. 94 | #endif 95 | 96 | static const linkom_atl_MIDL_PROC_FORMAT_STRING linkom_atl__MIDL_ProcFormatString = 97 | { 98 | 0, 99 | { 100 | 101 | /* Procedure SetSyntax */ 102 | 103 | 0x33, /* FC_AUTO_HANDLE */ 104 | 0x6c, /* Old Flags: object, Oi2 */ 105 | /* 2 */ NdrFcLong( 0x0 ), /* 0 */ 106 | /* 6 */ NdrFcShort( 0x3 ), /* 3 */ 107 | /* 8 */ NdrFcShort( 0x28 ), /* X64 Stack size/offset = 40 */ 108 | /* 10 */ NdrFcShort( 0x0 ), /* 0 */ 109 | /* 12 */ NdrFcShort( 0x24 ), /* 36 */ 110 | /* 14 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */ 111 | 0x4, /* 4 */ 112 | /* 16 */ 0xa, /* 10 */ 113 | 0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */ 114 | /* 18 */ NdrFcShort( 0x1 ), /* 1 */ 115 | /* 20 */ NdrFcShort( 0x1 ), /* 1 */ 116 | /* 22 */ NdrFcShort( 0x0 ), /* 0 */ 117 | /* 24 */ NdrFcShort( 0x0 ), /* 0 */ 118 | 119 | /* Parameter syntaxSpec */ 120 | 121 | /* 26 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ 122 | /* 28 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */ 123 | /* 30 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ 124 | 125 | /* Parameter invalidToken */ 126 | 127 | /* 32 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */ 128 | /* 34 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */ 129 | /* 36 */ NdrFcShort( 0x2e ), /* Type Offset=46 */ 130 | 131 | /* Parameter reasonCode */ 132 | 133 | /* 38 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ 134 | /* 40 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */ 135 | /* 42 */ 0x8, /* FC_LONG */ 136 | 0x0, /* 0 */ 137 | 138 | /* Return value */ 139 | 140 | /* 44 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ 141 | /* 46 */ NdrFcShort( 0x20 ), /* X64 Stack size/offset = 32 */ 142 | /* 48 */ 0x8, /* FC_LONG */ 143 | 0x0, /* 0 */ 144 | 145 | /* Procedure Parse */ 146 | 147 | /* 50 */ 0x33, /* FC_AUTO_HANDLE */ 148 | 0x6c, /* Old Flags: object, Oi2 */ 149 | /* 52 */ NdrFcLong( 0x0 ), /* 0 */ 150 | /* 56 */ NdrFcShort( 0x4 ), /* 4 */ 151 | /* 58 */ NdrFcShort( 0x28 ), /* X64 Stack size/offset = 40 */ 152 | /* 60 */ NdrFcShort( 0x0 ), /* 0 */ 153 | /* 62 */ NdrFcShort( 0x24 ), /* 36 */ 154 | /* 64 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */ 155 | 0x4, /* 4 */ 156 | /* 66 */ 0xa, /* 10 */ 157 | 0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */ 158 | /* 68 */ NdrFcShort( 0x1 ), /* 1 */ 159 | /* 70 */ NdrFcShort( 0x1 ), /* 1 */ 160 | /* 72 */ NdrFcShort( 0x0 ), /* 0 */ 161 | /* 74 */ NdrFcShort( 0x0 ), /* 0 */ 162 | 163 | /* Parameter commandLine */ 164 | 165 | /* 76 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ 166 | /* 78 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */ 167 | /* 80 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ 168 | 169 | /* Parameter invalidArg */ 170 | 171 | /* 82 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */ 172 | /* 84 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */ 173 | /* 86 */ NdrFcShort( 0x2e ), /* Type Offset=46 */ 174 | 175 | /* Parameter reasonCode */ 176 | 177 | /* 88 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ 178 | /* 90 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */ 179 | /* 92 */ 0x8, /* FC_LONG */ 180 | 0x0, /* 0 */ 181 | 182 | /* Return value */ 183 | 184 | /* 94 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ 185 | /* 96 */ NdrFcShort( 0x20 ), /* X64 Stack size/offset = 32 */ 186 | /* 98 */ 0x8, /* FC_LONG */ 187 | 0x0, /* 0 */ 188 | 189 | /* Procedure IsParamPresent */ 190 | 191 | /* 100 */ 0x33, /* FC_AUTO_HANDLE */ 192 | 0x6c, /* Old Flags: object, Oi2 */ 193 | /* 102 */ NdrFcLong( 0x0 ), /* 0 */ 194 | /* 106 */ NdrFcShort( 0x5 ), /* 5 */ 195 | /* 108 */ NdrFcShort( 0x20 ), /* X64 Stack size/offset = 32 */ 196 | /* 110 */ NdrFcShort( 0x0 ), /* 0 */ 197 | /* 112 */ NdrFcShort( 0x24 ), /* 36 */ 198 | /* 114 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ 199 | 0x3, /* 3 */ 200 | /* 116 */ 0xa, /* 10 */ 201 | 0x5, /* Ext Flags: new corr desc, srv corr check, */ 202 | /* 118 */ NdrFcShort( 0x0 ), /* 0 */ 203 | /* 120 */ NdrFcShort( 0x1 ), /* 1 */ 204 | /* 122 */ NdrFcShort( 0x0 ), /* 0 */ 205 | /* 124 */ NdrFcShort( 0x0 ), /* 0 */ 206 | 207 | /* Parameter paramName */ 208 | 209 | /* 126 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ 210 | /* 128 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */ 211 | /* 130 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ 212 | 213 | /* Parameter bPresent */ 214 | 215 | /* 132 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ 216 | /* 134 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */ 217 | /* 136 */ 0x8, /* FC_LONG */ 218 | 0x0, /* 0 */ 219 | 220 | /* Return value */ 221 | 222 | /* 138 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ 223 | /* 140 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */ 224 | /* 142 */ 0x8, /* FC_LONG */ 225 | 0x0, /* 0 */ 226 | 227 | /* Procedure GetParamValue */ 228 | 229 | /* 144 */ 0x33, /* FC_AUTO_HANDLE */ 230 | 0x6c, /* Old Flags: object, Oi2 */ 231 | /* 146 */ NdrFcLong( 0x0 ), /* 0 */ 232 | /* 150 */ NdrFcShort( 0x6 ), /* 6 */ 233 | /* 152 */ NdrFcShort( 0x28 ), /* X64 Stack size/offset = 40 */ 234 | /* 154 */ NdrFcShort( 0x0 ), /* 0 */ 235 | /* 156 */ NdrFcShort( 0x24 ), /* 36 */ 236 | /* 158 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */ 237 | 0x4, /* 4 */ 238 | /* 160 */ 0xa, /* 10 */ 239 | 0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */ 240 | /* 162 */ NdrFcShort( 0x1 ), /* 1 */ 241 | /* 164 */ NdrFcShort( 0x1 ), /* 1 */ 242 | /* 166 */ NdrFcShort( 0x0 ), /* 0 */ 243 | /* 168 */ NdrFcShort( 0x0 ), /* 0 */ 244 | 245 | /* Parameter paramName */ 246 | 247 | /* 170 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ 248 | /* 172 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */ 249 | /* 174 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ 250 | 251 | /* Parameter paramValue */ 252 | 253 | /* 176 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */ 254 | /* 178 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */ 255 | /* 180 */ NdrFcShort( 0x2e ), /* Type Offset=46 */ 256 | 257 | /* Parameter reasonCode */ 258 | 259 | /* 182 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ 260 | /* 184 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */ 261 | /* 186 */ 0x8, /* FC_LONG */ 262 | 0x0, /* 0 */ 263 | 264 | /* Return value */ 265 | 266 | /* 188 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ 267 | /* 190 */ NdrFcShort( 0x20 ), /* X64 Stack size/offset = 32 */ 268 | /* 192 */ 0x8, /* FC_LONG */ 269 | 0x0, /* 0 */ 270 | 271 | /* Procedure GetExtErrorString */ 272 | 273 | /* 194 */ 0x33, /* FC_AUTO_HANDLE */ 274 | 0x6c, /* Old Flags: object, Oi2 */ 275 | /* 196 */ NdrFcLong( 0x0 ), /* 0 */ 276 | /* 200 */ NdrFcShort( 0x7 ), /* 7 */ 277 | /* 202 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */ 278 | /* 204 */ NdrFcShort( 0x0 ), /* 0 */ 279 | /* 206 */ NdrFcShort( 0x8 ), /* 8 */ 280 | /* 208 */ 0x45, /* Oi2 Flags: srv must size, has return, has ext, */ 281 | 0x2, /* 2 */ 282 | /* 210 */ 0xa, /* 10 */ 283 | 0x3, /* Ext Flags: new corr desc, clt corr check, */ 284 | /* 212 */ NdrFcShort( 0x1 ), /* 1 */ 285 | /* 214 */ NdrFcShort( 0x0 ), /* 0 */ 286 | /* 216 */ NdrFcShort( 0x0 ), /* 0 */ 287 | /* 218 */ NdrFcShort( 0x0 ), /* 0 */ 288 | 289 | /* Parameter errString */ 290 | 291 | /* 220 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */ 292 | /* 222 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */ 293 | /* 224 */ NdrFcShort( 0x2e ), /* Type Offset=46 */ 294 | 295 | /* Return value */ 296 | 297 | /* 226 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ 298 | /* 228 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */ 299 | /* 230 */ 0x8, /* FC_LONG */ 300 | 0x0, /* 0 */ 301 | 302 | 0x0 303 | } 304 | }; 305 | 306 | static const linkom_atl_MIDL_TYPE_FORMAT_STRING linkom_atl__MIDL_TypeFormatString = 307 | { 308 | 0, 309 | { 310 | NdrFcShort( 0x0 ), /* 0 */ 311 | /* 2 */ 312 | 0x12, 0x0, /* FC_UP */ 313 | /* 4 */ NdrFcShort( 0xe ), /* Offset= 14 (18) */ 314 | /* 6 */ 315 | 0x1b, /* FC_CARRAY */ 316 | 0x1, /* 1 */ 317 | /* 8 */ NdrFcShort( 0x2 ), /* 2 */ 318 | /* 10 */ 0x9, /* Corr desc: FC_ULONG */ 319 | 0x0, /* */ 320 | /* 12 */ NdrFcShort( 0xfffc ), /* -4 */ 321 | /* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */ 322 | /* 16 */ 0x6, /* FC_SHORT */ 323 | 0x5b, /* FC_END */ 324 | /* 18 */ 325 | 0x17, /* FC_CSTRUCT */ 326 | 0x3, /* 3 */ 327 | /* 20 */ NdrFcShort( 0x8 ), /* 8 */ 328 | /* 22 */ NdrFcShort( 0xfff0 ), /* Offset= -16 (6) */ 329 | /* 24 */ 0x8, /* FC_LONG */ 330 | 0x8, /* FC_LONG */ 331 | /* 26 */ 0x5c, /* FC_PAD */ 332 | 0x5b, /* FC_END */ 333 | /* 28 */ 0xb4, /* FC_USER_MARSHAL */ 334 | 0x83, /* 131 */ 335 | /* 30 */ NdrFcShort( 0x0 ), /* 0 */ 336 | /* 32 */ NdrFcShort( 0x8 ), /* 8 */ 337 | /* 34 */ NdrFcShort( 0x0 ), /* 0 */ 338 | /* 36 */ NdrFcShort( 0xffde ), /* Offset= -34 (2) */ 339 | /* 38 */ 340 | 0x11, 0x4, /* FC_RP [alloced_on_stack] */ 341 | /* 40 */ NdrFcShort( 0x6 ), /* Offset= 6 (46) */ 342 | /* 42 */ 343 | 0x13, 0x0, /* FC_OP */ 344 | /* 44 */ NdrFcShort( 0xffe6 ), /* Offset= -26 (18) */ 345 | /* 46 */ 0xb4, /* FC_USER_MARSHAL */ 346 | 0x83, /* 131 */ 347 | /* 48 */ NdrFcShort( 0x0 ), /* 0 */ 348 | /* 50 */ NdrFcShort( 0x8 ), /* 8 */ 349 | /* 52 */ NdrFcShort( 0x0 ), /* 0 */ 350 | /* 54 */ NdrFcShort( 0xfff4 ), /* Offset= -12 (42) */ 351 | /* 56 */ 352 | 0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */ 353 | /* 58 */ 0x8, /* FC_LONG */ 354 | 0x5c, /* FC_PAD */ 355 | 356 | 0x0 357 | } 358 | }; 359 | 360 | static const USER_MARSHAL_ROUTINE_QUADRUPLE UserMarshalRoutines[ WIRE_MARSHAL_TABLE_SIZE ] = 361 | { 362 | 363 | { 364 | BSTR_UserSize 365 | ,BSTR_UserMarshal 366 | ,BSTR_UserUnmarshal 367 | ,BSTR_UserFree 368 | } 369 | 370 | }; 371 | 372 | 373 | 374 | /* Object interface: IUnknown, ver. 0.0, 375 | GUID={0x00000000,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ 376 | 377 | 378 | /* Object interface: ILinkom, ver. 0.0, 379 | GUID={0x601BF357,0xE6D9,0x4E3E,{0x8D,0xEC,0x90,0x8E,0x55,0x9A,0x9D,0x69}} */ 380 | 381 | #pragma code_seg(".orpc") 382 | static const unsigned short ILinkom_FormatStringOffsetTable[] = 383 | { 384 | 0, 385 | 50, 386 | 100, 387 | 144, 388 | 194 389 | }; 390 | 391 | static const MIDL_STUBLESS_PROXY_INFO ILinkom_ProxyInfo = 392 | { 393 | &Object_StubDesc, 394 | linkom_atl__MIDL_ProcFormatString.Format, 395 | &ILinkom_FormatStringOffsetTable[-3], 396 | 0, 397 | 0, 398 | 0 399 | }; 400 | 401 | 402 | static const MIDL_SERVER_INFO ILinkom_ServerInfo = 403 | { 404 | &Object_StubDesc, 405 | 0, 406 | linkom_atl__MIDL_ProcFormatString.Format, 407 | &ILinkom_FormatStringOffsetTable[-3], 408 | 0, 409 | 0, 410 | 0, 411 | 0}; 412 | CINTERFACE_PROXY_VTABLE(8) _ILinkomProxyVtbl = 413 | { 414 | &ILinkom_ProxyInfo, 415 | &IID_ILinkom, 416 | IUnknown_QueryInterface_Proxy, 417 | IUnknown_AddRef_Proxy, 418 | IUnknown_Release_Proxy , 419 | (void *) (INT_PTR) -1 /* ILinkom::SetSyntax */ , 420 | (void *) (INT_PTR) -1 /* ILinkom::Parse */ , 421 | (void *) (INT_PTR) -1 /* ILinkom::IsParamPresent */ , 422 | (void *) (INT_PTR) -1 /* ILinkom::GetParamValue */ , 423 | (void *) (INT_PTR) -1 /* ILinkom::GetExtErrorString */ 424 | }; 425 | 426 | const CInterfaceStubVtbl _ILinkomStubVtbl = 427 | { 428 | &IID_ILinkom, 429 | &ILinkom_ServerInfo, 430 | 8, 431 | 0, /* pure interpreted */ 432 | CStdStubBuffer_METHODS 433 | }; 434 | 435 | static const MIDL_STUB_DESC Object_StubDesc = 436 | { 437 | 0, 438 | NdrOleAllocate, 439 | NdrOleFree, 440 | 0, 441 | 0, 442 | 0, 443 | 0, 444 | 0, 445 | linkom_atl__MIDL_TypeFormatString.Format, 446 | 1, /* -error bounds_check flag */ 447 | 0x50002, /* Ndr library version */ 448 | 0, 449 | 0x800025b, /* MIDL Version 8.0.603 */ 450 | 0, 451 | UserMarshalRoutines, 452 | 0, /* notify & notify_flag routine table */ 453 | 0x1, /* MIDL flag */ 454 | 0, /* cs routines */ 455 | 0, /* proxy/server info */ 456 | 0 457 | }; 458 | 459 | const CInterfaceProxyVtbl * const _linkom_atl_ProxyVtblList[] = 460 | { 461 | ( CInterfaceProxyVtbl *) &_ILinkomProxyVtbl, 462 | 0 463 | }; 464 | 465 | const CInterfaceStubVtbl * const _linkom_atl_StubVtblList[] = 466 | { 467 | ( CInterfaceStubVtbl *) &_ILinkomStubVtbl, 468 | 0 469 | }; 470 | 471 | PCInterfaceName const _linkom_atl_InterfaceNamesList[] = 472 | { 473 | "ILinkom", 474 | 0 475 | }; 476 | 477 | 478 | #define _linkom_atl_CHECK_IID(n) IID_GENERIC_CHECK_IID( _linkom_atl, pIID, n) 479 | 480 | int __stdcall _linkom_atl_IID_Lookup( const IID * pIID, int * pIndex ) 481 | { 482 | 483 | if(!_linkom_atl_CHECK_IID(0)) 484 | { 485 | *pIndex = 0; 486 | return 1; 487 | } 488 | 489 | return 0; 490 | } 491 | 492 | const ExtendedProxyFileInfo linkom_atl_ProxyFileInfo = 493 | { 494 | (PCInterfaceProxyVtblList *) & _linkom_atl_ProxyVtblList, 495 | (PCInterfaceStubVtblList *) & _linkom_atl_StubVtblList, 496 | (const PCInterfaceName * ) & _linkom_atl_InterfaceNamesList, 497 | 0, /* no delegation */ 498 | & _linkom_atl_IID_Lookup, 499 | 1, 500 | 2, 501 | 0, /* table of [async_uuid] interfaces */ 502 | 0, /* Filler1 */ 503 | 0, /* Filler2 */ 504 | 0 /* Filler3 */ 505 | }; 506 | #if _MSC_VER >= 1200 507 | #pragma warning(pop) 508 | #endif 509 | 510 | 511 | #endif /* defined(_M_AMD64)*/ 512 | 513 | -------------------------------------------------------------------------------- /COM/linkom_atl/linkom_atlps.def: -------------------------------------------------------------------------------- 1 | 2 | LIBRARY 3 | 4 | EXPORTS 5 | DllGetClassObject PRIVATE 6 | DllCanUnloadNow PRIVATE 7 | DllRegisterServer PRIVATE 8 | DllUnregisterServer PRIVATE 9 | -------------------------------------------------------------------------------- /COM/linkom_atl/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hernandp/linkom/53609c48d4813e957ab31b42de53f85c29c45bcc/COM/linkom_atl/resource.h -------------------------------------------------------------------------------- /COM/linkom_atl/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // linkom_atl.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | -------------------------------------------------------------------------------- /COM/linkom_atl/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, 3 | // but are changed infrequently 4 | 5 | #pragma once 6 | 7 | #ifndef STRICT 8 | #define STRICT 9 | #endif 10 | 11 | #include "targetver.h" 12 | 13 | #define _ATL_APARTMENT_THREADED 14 | 15 | #define _ATL_NO_AUTOMATIC_NAMESPACE 16 | 17 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit 18 | 19 | 20 | #define ATL_NO_ASSERT_ON_DESTROY_NONEXISTENT_WINDOW 21 | 22 | #include "resource.h" 23 | #include 24 | #include 25 | #include 26 | -------------------------------------------------------------------------------- /COM/linkom_atl/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Hernán Di Pietro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /linkom.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This file is part of Linkom Library 4 | 5 | Copyright (c) 2016 Hernán Di Pietro 6 | 7 | Wide-char Safe string functions 8 | Copyright 1999 Alexandre Julliard 9 | Copyright 2000 Jon Griffiths 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in all 19 | copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | SOFTWARE. 28 | 29 | */ 30 | #ifndef __LINKOM_H__f82e85a35f914826a6af35aa02839625 31 | #define __LINKOM_H__f82e85a35f914826a6af35aa02839625 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #if defined (__GNUC__) 44 | #define __STDC_WANT_LIB_EXT1__ 1 45 | #include 46 | #include 47 | #define _wcsdup wcsdup 48 | #define _wcsicmp wcscasecmp 49 | #define wcstok_s wcstok 50 | #define _LK_MIN(a,b) ( (a) < (b) ? (a) : (b) ) 51 | static int wcscpy_s(wchar_t* dest, size_t numElem, const wchar_t* src) 52 | { 53 | size_t size = 0; 54 | if(!dest || !numElem) 55 | return EINVAL; 56 | 57 | dest[0] = 0; 58 | if (!src) 59 | return EINVAL; 60 | 61 | size = wcslen(src) + 1; 62 | if (size > numElem) 63 | return ERANGE; 64 | memcpy( dest, src, size * sizeof( wchar_t )); 65 | return 0; 66 | } 67 | 68 | static int wcscat_s(wchar_t* dst, size_t numElem, const wchar_t* src) 69 | { 70 | wchar_t* ptr = dst; 71 | if (!dst || numElem==0) 72 | return EINVAL; 73 | if (!src) 74 | { 75 | dst[0] = 0; 76 | return EINVAL; 77 | } 78 | 79 | while (ptr < dst + numElem && *ptr != 0) ptr++; 80 | while (ptr < dst + numElem) 81 | { 82 | if ((*ptr++ = *src++) == 0) return 0; 83 | } 84 | dst[0] = 0; 85 | return ERANGE; 86 | } 87 | 88 | static int wcsncpy_s(wchar_t* dst, size_t numElem, const wchar_t* src, 89 | size_t count) 90 | { 91 | size_t size = 0; 92 | if (!dst || !numElem) 93 | return EINVAL; 94 | 95 | dst[0] = 0; 96 | if (!src) 97 | return EINVAL; 98 | 99 | size = _LK_MIN(wcslen(src), count); 100 | if (size >= numElem) 101 | { 102 | return ERANGE; 103 | } 104 | memcpy ( dst, src, size * sizeof (wchar_t) ); 105 | dst[size] = 0; 106 | return 0; 107 | } 108 | 109 | #endif 110 | 111 | #ifdef LK_ENABLE_TRACE 112 | #define _LKTRACE(...) fprintf (stderr, __VA_ARGS__) 113 | #define _LKTRACEW(...) fwprintf(stderr, __VA_ARGS__) 114 | #else 115 | #define _LKTRACE(...) 116 | #define _LKTRACEW(...) 117 | #endif 118 | 119 | #define LK_ARRAYSIZE(x) ((sizeof(x) / sizeof(*(x))) / \ 120 | (size_t)(!(sizeof(x) % sizeof(*(x))))) 121 | 122 | /* --------------------------------------------------------------------------- 123 | Error codes (inspired by MS HRESULTs) 124 | ---------------------------------------------------------------------------*/ 125 | typedef enum 126 | { 127 | LK_R_OK = 0x00000000, 128 | LK_R_FALSE = 0x00000000, 129 | LK_R_TRUE = 0x00000001, 130 | LK_E_MALLOC = 0xEEEE0001, 131 | LK_E_NULLPOINTER = 0xEEEE0002, 132 | LK_E_UNINITIALIZED = 0xEEEE0003, 133 | LK_E_INVALIDARG = 0xEEEE0004, 134 | LK_E_ALREADYINIT = 0xEEEE0005, 135 | LK_E_LISTFULL = 0xEEEE0006, 136 | LK_E_NOTFOUND = 0xEEEE0007, 137 | LK_E_OUTOFBOUNDS = 0xEEEE0008, 138 | LK_E_INVALIDSYNTAX = 0xEEEE1000, 139 | LK_E_UNKNOWNARG = 0xEEEE1001, 140 | LK_E_DUPLICATEARG = 0xEEEE1002, 141 | LK_E_DUPLICATETOKEN = 0xEEEE1003, 142 | LK_E_TYPEMISMATCH = 0xEEEE1004, 143 | LK_E_MISSINGARG = 0xEEEE1005, 144 | LK_E_MISSINGVALUE = 0xEEEE1006, 145 | LK_E_MISSINGNAMARG = 0xEEEE1007, 146 | LK_E_DUPLICATEGROUPITEM = 0xEEEE1008, 147 | LK_E_CONTRADICTARG = 0xEEEE1009, 148 | LK_E_NOGROUPMEMBERCHOSEN= 0xEEEE100A, 149 | LK_E_TOKENLENGTH = 0xEEEE100B, 150 | LK_E_TOKENCOUNT = 0xEEEE100C, 151 | LK_E_GROUPCOUNT = 0xEEEE100D, 152 | LK_E_GROUPMEMBERCOUNT = 0xEEEE100E, 153 | LK_E_VALUELENGTH = 0xEEEE100F, 154 | LK_E_UNDEFINED = 0xEEEE1100, 155 | LK_E_INSUFFICIENTBUFFER = 0xEEEE1101 156 | } LK_RESULT; 157 | #define LK_SUCCESS(x) (( (x) == 0)|| ((x)==1)) 158 | 159 | /* --------------------------------------------------------------------------- 160 | Error message table 161 | ---------------------------------------------------------------------------*/ 162 | typedef struct _lk_msgtab 163 | { 164 | LK_RESULT res; 165 | wchar_t* wErrMsg; 166 | } LK_MESSAGETABLE; 167 | 168 | static const LK_MESSAGETABLE g_lkErrTable[] = { 169 | LK_R_OK, L"Operation successful", 170 | LK_E_MALLOC, L"Memory allocation error", 171 | LK_E_NULLPOINTER, L"Null pointer argument", 172 | LK_E_UNINITIALIZED, L"Library uninitialized", 173 | LK_E_INVALIDARG, L"Invalid argument: %s", 174 | LK_E_ALREADYINIT, L"Already initialized", 175 | LK_E_LISTFULL, L"List full", 176 | LK_E_NOTFOUND, L"Parameter not found: %s", 177 | LK_E_OUTOFBOUNDS, L"Argument out of bounds", 178 | LK_E_INVALIDSYNTAX, L"Invalid syntax specification", 179 | LK_E_UNKNOWNARG, L"Unknown argument: %s", 180 | LK_E_DUPLICATEARG, L"Duplicate argument: %s", 181 | LK_E_DUPLICATETOKEN, L"Duplicate syntax token: %s", 182 | LK_E_TYPEMISMATCH, L"Type mismatch for argument: %s", 183 | LK_E_MISSINGARG, L"Required argument missing: %s", 184 | LK_E_MISSINGVALUE, L"Required value missing for parameter: %s", 185 | LK_E_MISSINGNAMARG, L"Required named argument missing: %s", 186 | LK_E_DUPLICATEGROUPITEM, L"Duplicate group argument: %s", 187 | LK_E_CONTRADICTARG, L"Contradictory arguments specified: %s", 188 | LK_E_NOGROUPMEMBERCHOSEN, L"Required group argument missing: %s", 189 | LK_E_TOKENLENGTH, L"Token length exceeded", 190 | LK_E_TOKENCOUNT, L"Token count exceeded", 191 | LK_E_GROUPCOUNT, L"Group count exceeded", 192 | LK_E_GROUPMEMBERCOUNT, L"Group member count exceeded", 193 | LK_E_VALUELENGTH, L"Parameter value length exceeded", 194 | LK_E_UNDEFINED, L"Parameter is undefined", 195 | LK_E_INSUFFICIENTBUFFER, L"Specified buffer size is insufficient" 196 | }; 197 | 198 | #define LK_RETURN_STERR(_lkerr) { _Lk_StoreExtErr(_lkerr, 0); return _lkerr; } 199 | #define LK_RETURN_STERR1(_lkerr,_arg) { _Lk_StoreExtErr(_lkerr, _arg); return _lkerr; } 200 | 201 | /* --------------------------------------------------------------------------- 202 | Tunable limits, modify as you wish 203 | ---------------------------------------------------------------------------*/ 204 | #ifndef LK_DEFINE_USER_LIMITS 205 | #define LK_MAX_TOKENARG_LEN 256 /* Maximum argument and token length */ 206 | #define LK_MAX_TOKENARG_COUNT 256 /* Maximum argument and token count */ 207 | #define LK_MAX_GROUP_COUNT 32 /* Maximum group count */ 208 | #define LK_MAX_PARAMVALUE_LEN 2048 /* Max str length for param. values*/ 209 | #endif 210 | 211 | #define LK_MAX_ERRORBUFFER_LEN 1024 212 | #define LK_MAX_GROUP_DESCRIPTION 256 213 | 214 | /* --------------------------------------------------------------------------- 215 | Token List types 216 | ---------------------------------------------------------------------------*/ 217 | typedef enum tagLK_TOKEN_TYPE 218 | { 219 | LK_TOKEN_TYPE_NAMED_ARGUMENT, 220 | LK_TOKEN_TYPE_PARAMETER, 221 | LK_TOKEN_TYPE_PARAMETER_VAL, 222 | LK_TOKEN_TYPE_PARAMETER_VAL_OPT, 223 | LK_TOKEN_TYPE_PARAMETER_GROUP 224 | } LK_TOKEN_TYPE; 225 | 226 | typedef struct tagLK_TOKEN_ITEM 227 | { 228 | wchar_t name[LK_MAX_TOKENARG_LEN]; 229 | LK_TOKEN_TYPE type; 230 | int memberOf; // mutex-group member,if any 231 | } LK_TOKEN_ITEM; 232 | 233 | typedef struct tagLK_TOKEN_LIST_ENTRY 234 | { 235 | bool isOptional; 236 | LK_TOKEN_ITEM item; 237 | } LK_TOKEN_LIST_ENTRY; 238 | 239 | static wchar_t* g_lkTypeStr[] = 240 | { 241 | L"NAMED_ARGUMENT", L"PARAMETER", L"PARAMETER_VAL", 242 | L"PARAMETER_VAL_OPT", L"GROUP" 243 | }; 244 | 245 | /* This is a special name specifying a non-parameter argument 246 | that's waiting to be matched against a syntax token */ 247 | 248 | #define LK_UNMAPPED_ARG_NAME L"\0xFA\00\0xFB\00\0xFC\00\0xFD\00\00\00" 249 | 250 | /* ---------------------------------------------------------------------------- 251 | Argument List types 252 | ---------------------------------------------------------------------------*/ 253 | typedef struct tagARGUMENT 254 | { 255 | wchar_t name[LK_MAX_TOKENARG_LEN]; 256 | wchar_t value[LK_MAX_PARAMVALUE_LEN]; 257 | bool hasValue; 258 | bool isParam; 259 | bool isMapped; 260 | bool isProcessed; 261 | int matchingGroup; 262 | } LK_ARGUMENT; 263 | 264 | typedef struct tagARGLIST 265 | { 266 | LK_ARGUMENT item[LK_MAX_TOKENARG_COUNT]; 267 | size_t count; 268 | } LK_ARGLIST; 269 | 270 | /* ---------------------------------------------------------------------------- 271 | Group data 272 | ---------------------------------------------------------------------------*/ 273 | 274 | #define LK_NOGROUP -1 275 | typedef struct tagLK_GROUPINFO 276 | { 277 | wchar_t* selectedParam; 278 | bool isOptional; 279 | wchar_t description[LK_MAX_GROUP_DESCRIPTION]; 280 | } LK_GROUPINFO; 281 | 282 | /* -------------------------------------------------------------------------- 283 | Globals 284 | --------------------------------------------------------------------------*/ 285 | static LK_ARGLIST g_argList; 286 | static LK_TOKEN_LIST_ENTRY* g_tokenList; 287 | static size_t g_tokenCount, g_tokenMaxCount; 288 | static bool g_syntaxValid; 289 | static size_t g_groupCount; 290 | static LK_GROUPINFO g_groupInfo[LK_MAX_GROUP_COUNT]; 291 | static wchar_t g_exErrBuffer[LK_MAX_ERRORBUFFER_LEN]; 292 | /* --------------------------------------------------------------------------*/ 293 | LK_RESULT _Lk_TokenListInit(size_t maxCount) 294 | { 295 | if (g_tokenList) 296 | return LK_E_ALREADYINIT; 297 | if (maxCount == 0) 298 | return LK_E_INVALIDARG; 299 | g_tokenList = (LK_TOKEN_LIST_ENTRY*)malloc(maxCount * sizeof (LK_TOKEN_LIST_ENTRY)); 300 | if (!g_tokenList) 301 | return LK_E_MALLOC; 302 | 303 | g_tokenCount = 0; 304 | g_tokenMaxCount = maxCount; 305 | g_groupCount = 0; 306 | return LK_R_OK; 307 | } 308 | /* --------------------------------------------------------------------------*/ 309 | LK_RESULT _Lk_TokenListClear() 310 | { 311 | if (g_tokenMaxCount == 0) 312 | return LK_E_UNINITIALIZED; 313 | size_t i; 314 | for (i = 0 ; i < g_tokenMaxCount; ++i) 315 | memset (&g_tokenList[i], 0, sizeof(LK_TOKEN_LIST_ENTRY)); 316 | return LK_R_OK; 317 | } 318 | /* --------------------------------------------------------------------------*/ 319 | LK_RESULT _Lk_TokenFindName(const wchar_t* name) 320 | { 321 | for (size_t i = 0; i < g_tokenCount; ++i) 322 | { 323 | //wprintf(L"_Lk_TokenFindName (%s) == (%s)\n", g_tokenList[i].item.name, name); 324 | if (!_wcsicmp(g_tokenList[i].item.name, name)) 325 | return LK_R_OK; 326 | } 327 | return LK_E_NOTFOUND; 328 | } 329 | /* --------------------------------------------------------------------------*/ 330 | LK_RESULT _Lk_TokenAdd(LK_TOKEN_ITEM* item, bool isOptional, bool allowDuplicate) 331 | { 332 | if (g_tokenCount == g_tokenMaxCount) 333 | return LK_E_LISTFULL; 334 | 335 | //wprintf(L">>_Lk_TokenAdd(%s)\n", item->name); 336 | 337 | if (!allowDuplicate && (_Lk_TokenFindName(item->name) == LK_R_OK)) 338 | return LK_E_DUPLICATETOKEN; 339 | 340 | g_tokenList[g_tokenCount].isOptional = isOptional; 341 | g_tokenList[g_tokenCount].item.type = item->type; 342 | g_tokenList[g_tokenCount].item.memberOf = item->memberOf; 343 | wcscpy_s(g_tokenList[g_tokenCount].item.name, 344 | LK_MAX_TOKENARG_LEN, item->name); 345 | g_tokenCount++; 346 | return LK_R_OK; 347 | } 348 | 349 | /* --------------------------------------------------------------------------*/ 350 | size_t _Lk_TokenGetCount() { return g_tokenCount; } 351 | 352 | /* --------------------------------------------------------------------------*/ 353 | LK_RESULT _Lk_TokenGet(size_t idx, LK_TOKEN_LIST_ENTRY** pListEntry) 354 | { 355 | if (idx >= g_tokenCount) 356 | return LK_E_OUTOFBOUNDS; 357 | 358 | *pListEntry = &g_tokenList[idx]; 359 | return LK_R_OK; 360 | } 361 | 362 | void _Lk_TokenListFree() 363 | { 364 | if (g_tokenList) 365 | { 366 | free (g_tokenList); 367 | g_tokenList = NULL; 368 | g_tokenCount = 0; 369 | g_tokenMaxCount=0; 370 | } 371 | } 372 | 373 | /* ---------------------------------------------------------------------------*/ 374 | 375 | LK_RESULT _Lk_ClassifyTokenR(wchar_t* token, bool isOptional) 376 | { 377 | assert(token); 378 | _LKTRACEW(L" %s (%s,%d)\n", __FUNCTION__, token, isOptional); 379 | 380 | const size_t len = wcslen(token); 381 | if (len > LK_MAX_TOKENARG_LEN) 382 | return LK_E_TOKENLENGTH; 383 | 384 | if ((token[0] == L'[') && (token[len-1] == L']') && !isOptional) 385 | { 386 | token[len-1] = L'\0'; 387 | return _Lk_ClassifyTokenR(&token[1], true); 388 | } 389 | // minimal accepted form: {/x|/y} (length:7) 390 | else if ((token[0] == L'{') && (token[len-1] == L'}') && len >= 7) 391 | { 392 | LK_RESULT r; 393 | if (g_groupCount == LK_MAX_GROUP_COUNT) 394 | return LK_E_GROUPCOUNT; 395 | 396 | g_groupInfo[g_groupCount].isOptional = isOptional; 397 | g_groupInfo[g_groupCount].selectedParam = NULL; 398 | wcsncpy_s(g_groupInfo[g_groupCount].description, LK_MAX_GROUP_DESCRIPTION, &token[0], len); 399 | 400 | LK_TOKEN_ITEM item; 401 | 402 | _LKTRACEW(L" Group-type token, decomposing...\n"); 403 | int i = 1, iArgStart = i; 404 | do 405 | { 406 | if(token[i] == L'|' || token[i] == L'}') 407 | { 408 | if (token[iArgStart] != L'/') 409 | return LK_E_INVALIDSYNTAX; 410 | 411 | memset (item.name, 0, LK_MAX_TOKENARG_LEN); 412 | wcsncpy_s(item.name, LK_MAX_TOKENARG_LEN, &token[iArgStart], i - iArgStart); 413 | 414 | if (item.name[wcslen(item.name)-1] == L'}' ) 415 | item.name[wcslen(item.name)-1] = 0; 416 | 417 | size_t namelen = wcslen(item.name); 418 | 419 | _LKTRACEW(L" item.name = %s\n", item.name); 420 | size_t k = namelen-1; 421 | if (item.name[k] == L':' || item.name[k] == L'=') 422 | { 423 | _LKTRACEW(L" item.type = LK_TOKEN_TYPE_PARAMETER_VAL\n"); 424 | item.type = LK_TOKEN_TYPE_PARAMETER_VAL; 425 | item.name[k] = L'\0'; 426 | } 427 | else if (item.name[k] == L'?') 428 | { 429 | if (namelen == 2) // Hack to accept '/?' which is fairly common 430 | { 431 | _LKTRACEW(L" item.type = LK_TOKEN_TYPE_PARAMETER\n"); 432 | item.type = LK_TOKEN_TYPE_PARAMETER; 433 | item.name[k+1] = L'\0'; 434 | } 435 | else 436 | { 437 | _LKTRACEW(L" item.type = LK_TOKEN_TYPE_PARAMETER_VAL_OPT\n"); 438 | item.type = LK_TOKEN_TYPE_PARAMETER_VAL_OPT; 439 | item.name[k] = L'\0'; 440 | } 441 | } 442 | else 443 | { 444 | _LKTRACEW(L" item.type = LK_TOKEN_TYPE_PARAMETER\n"); 445 | item.type = LK_TOKEN_TYPE_PARAMETER; 446 | item.name[k+1] = L'\0'; 447 | } 448 | 449 | _LKTRACEW(L" item.memberOf = %Iu\n", g_groupCount); 450 | item.memberOf = (int) g_groupCount; 451 | r = _Lk_TokenAdd(&item, isOptional, false); 452 | if (r == LK_R_OK) 453 | iArgStart = i + 1; 454 | else 455 | { 456 | //printf("TkListAdditem res=0x%08x \n", r); 457 | if (r == LK_E_DUPLICATETOKEN) 458 | return LK_E_DUPLICATEGROUPITEM; 459 | break; 460 | } 461 | } 462 | } while (token[i++]); 463 | 464 | g_groupCount++; 465 | return LK_R_OK; 466 | } 467 | else if (token[0] == L'$' && len > 1) 468 | { 469 | LK_TOKEN_ITEM item; 470 | item.memberOf = LK_NOGROUP; 471 | wcsncpy_s(item.name, LK_MAX_TOKENARG_LEN, token, LK_MAX_TOKENARG_LEN); 472 | if (!isOptional) 473 | { 474 | _LKTRACEW(L" item.type = LK_TOKEN_TYPE_NAMED_ARGUMENT\n"); 475 | item.type = LK_TOKEN_TYPE_NAMED_ARGUMENT; 476 | return _Lk_TokenAdd(&item, isOptional, false); 477 | } 478 | } 479 | else if (token[0] == L'/') 480 | { 481 | LK_TOKEN_ITEM item; 482 | item.memberOf = LK_NOGROUP; 483 | wcsncpy_s(item.name, LK_MAX_TOKENARG_LEN, token, LK_MAX_TOKENARG_LEN); 484 | size_t namelen = wcslen(item.name); 485 | 486 | // Check if it's a parameter with (optional) value associated 487 | 488 | size_t k = namelen-1; 489 | if (token[k] == L':' || token[k] == L'=') 490 | { 491 | _LKTRACEW(L" item.type = LK_TOKEN_TYPE_PARAMETER_VAL\n"); 492 | item.type = LK_TOKEN_TYPE_PARAMETER_VAL; 493 | item.name[k] = L'\0'; 494 | } 495 | else if (token[k] == L'?') 496 | { 497 | if (namelen == 2) // Hack to accept '/?' which is fairly common 498 | { 499 | _LKTRACEW(L" item.type = LK_TOKEN_TYPE_PARAMETER\n"); 500 | item.type = LK_TOKEN_TYPE_PARAMETER; 501 | item.name[k+1] = L'\0'; 502 | } 503 | else 504 | { 505 | _LKTRACEW(L" item.type = LK_TOKEN_TYPE_PARAMETER_VAL_OPT\n"); 506 | item.type = LK_TOKEN_TYPE_PARAMETER_VAL_OPT; 507 | item.name[k] = L'\0'; 508 | } 509 | } 510 | else 511 | { 512 | _LKTRACEW(L" item.type = LK_TOKEN_TYPE_PARAMETER\n"); 513 | item.type = LK_TOKEN_TYPE_PARAMETER; 514 | item.name[k+1] = L'\0'; 515 | } 516 | return _Lk_TokenAdd(&item, isOptional, false); 517 | } 518 | return LK_E_INVALIDSYNTAX; 519 | } 520 | 521 | /* --------------------------------------------------------------------------*/ 522 | LK_RESULT _Lk_ClassifyToken(wchar_t* token) 523 | { 524 | return _Lk_ClassifyTokenR(token, false); 525 | } 526 | /* ---------------------------------------------------------------------------*/ 527 | LK_RESULT _Lk_FindArgumentName(wchar_t* name, bool fMarkAsProcessed) { 528 | for (size_t i = 0; i < g_argList.count; i++) { 529 | if (!_wcsicmp(name, g_argList.item[i].name)) { 530 | if (fMarkAsProcessed) 531 | g_argList.item[i].isProcessed = true; 532 | return LK_R_TRUE; 533 | } 534 | } 535 | return LK_R_FALSE; 536 | } 537 | /*----------------------------------------------------------------------------*/ 538 | 539 | LK_RESULT _Lk_FindUnprocessedArg(wchar_t* outArg) { 540 | for (size_t i = 0; i < g_argList.count; i++) { 541 | if (!g_argList.item[i].isProcessed) 542 | { 543 | // If this an unprocessed named-argument, may be still is 544 | // unmapped to any token, so item[i].name is empty; in that 545 | // case we use the value instead, to return data. 546 | 547 | if (g_argList.item[i].name == NULL || wcslen(g_argList.item[i].name) == 0) 548 | wcscpy_s(outArg, LK_MAX_TOKENARG_LEN, g_argList.item[i].value); 549 | else 550 | wcscpy_s(outArg, LK_MAX_TOKENARG_LEN, g_argList.item[i].name); 551 | return LK_R_TRUE; 552 | } 553 | } 554 | return LK_R_FALSE; 555 | } 556 | 557 | /*----------------------------------------------------------------------------*/ 558 | LK_RESULT _Lk_EvalGroups(wchar_t* invalidArg) 559 | { 560 | size_t i; 561 | LK_TOKEN_LIST_ENTRY* pTok = NULL; 562 | 563 | wchar_t pTokName[LK_MAX_TOKENARG_LEN]; 564 | 565 | for (i = 0; i < g_groupCount; i++) 566 | g_groupInfo[i].selectedParam = NULL; 567 | 568 | for (i = 0; i < _Lk_TokenGetCount(); i++) 569 | { 570 | _Lk_TokenGet(i, &pTok); 571 | if ( pTok->item.memberOf != LK_NOGROUP ) 572 | { 573 | memset(pTokName, 0, sizeof(pTokName)); 574 | _LKTRACEW(L"_Lk_EvalGroups: Evaluating token %s (group:%d)\n", pTok->item.name,pTok->item.memberOf); 575 | size_t j; 576 | for (j = 0; j < g_argList.count; j++) 577 | { 578 | if (!_wcsicmp(g_argList.item[j].name, pTok->item.name)) 579 | { 580 | if (g_groupInfo[pTok->item.memberOf].selectedParam == NULL) 581 | { 582 | if (pTok->item.type == LK_TOKEN_TYPE_PARAMETER_VAL && !g_argList.item[j].hasValue) 583 | { 584 | _LKTRACEW(L"_Lk_EvalGroups: Argument %s potentially matched for group : %d, but missing value\n", 585 | g_argList.item[j].name, pTok->item.memberOf); 586 | wcscpy_s(invalidArg, LK_MAX_TOKENARG_LEN, g_argList.item[j].name); 587 | return LK_E_MISSINGVALUE; 588 | } 589 | 590 | _LKTRACEW(L"_Lk_EvalGroups: Argument %s matched for group : %d\n", g_argList.item[j].name,pTok->item.memberOf); 591 | g_groupInfo[pTok->item.memberOf].selectedParam = g_argList.item[j].name; 592 | g_argList.item[j].isProcessed = true; 593 | break; 594 | } 595 | else 596 | { 597 | //Already got an argument from this group 598 | //Return the parameters we detected as contradictory 599 | size_t cch = wcslen(g_groupInfo[pTok->item.memberOf].selectedParam) 600 | + wcslen(g_argList.item[j].name) + 2; 601 | wchar_t* invArgData = (wchar_t*) calloc (cch, sizeof(wchar_t)); 602 | if (!invArgData) 603 | return LK_E_MALLOC; 604 | wcscpy_s(invArgData,cch, g_groupInfo[pTok->item.memberOf].selectedParam); 605 | wcscat_s(invArgData, cch, L" "); 606 | wcscat_s(invArgData, cch, g_argList.item[j].name); 607 | wcscpy_s(invalidArg, LK_MAX_TOKENARG_LEN, invArgData); 608 | free(invArgData); 609 | return LK_E_CONTRADICTARG; 610 | } 611 | } 612 | } 613 | } 614 | } 615 | 616 | for (i = 0; i < g_groupCount; i++) 617 | { 618 | if (!g_groupInfo[i].selectedParam && !g_groupInfo[i].isOptional) 619 | { 620 | wcscpy_s(invalidArg, LK_MAX_TOKENARG_LEN, g_groupInfo[i].description); 621 | return LK_E_NOGROUPMEMBERCHOSEN; 622 | } 623 | } 624 | return LK_R_OK; 625 | } 626 | /* ---------------------------------------------------------------------------*/ 627 | LK_RESULT _Lk_MapNamedArgs() { 628 | _LKTRACE("_Lk_MapNamedArgs\n"); 629 | 630 | LK_TOKEN_LIST_ENTRY* pTok = NULL; 631 | size_t i = 0, j = 0; 632 | 633 | for (i = 0; i < _Lk_TokenGetCount(); i++) { 634 | _Lk_TokenGet(i, &pTok); 635 | 636 | _LKTRACEW(L" Got token %Iu/%Iu name=%s \t[%s] (Opt=%d) \n", i + 1, _Lk_TokenGetCount(), 637 | pTok->item.name, g_lkTypeStr[pTok->item.type], pTok->isOptional); 638 | 639 | if (pTok->item.type == LK_TOKEN_TYPE_NAMED_ARGUMENT) { 640 | 641 | // Search a command line argument to map with 642 | // this named-argument token 643 | 644 | for (j = 0; j < g_argList.count; j++) { 645 | if (!(g_argList.item[j].isParam || g_argList.item[j].isMapped)) { 646 | g_argList.item[j].isMapped = true; 647 | g_argList.item[j].isProcessed = true; 648 | break; 649 | } 650 | } 651 | wcscpy_s(g_argList.item[j].name, LK_MAX_TOKENARG_LEN, pTok->item.name); 652 | _LKTRACEW(L" Mapped named argument %s\n", pTok->item.name); 653 | } 654 | } 655 | 656 | return LK_R_OK; 657 | } 658 | /*---------------------------------------------------------------------------*/ 659 | 660 | LK_RESULT _Lk_GetParamValue(const wchar_t* paramName, wchar_t** paramValue) { 661 | 662 | if (!paramName | !paramValue | (paramName && wcslen(paramName) == 0)) 663 | return LK_E_INVALIDARG; 664 | 665 | size_t i; 666 | for (i = 0; i < g_argList.count; ++i) { 667 | if (!_wcsicmp(paramName, g_argList.item[i].name)) { 668 | if (g_argList.item[i].hasValue) { 669 | *paramValue = g_argList.item[i].value; 670 | return LK_R_OK; 671 | } else { 672 | *paramValue = NULL; 673 | return LK_E_UNDEFINED; 674 | } 675 | } 676 | } 677 | *paramValue = NULL; 678 | return LK_E_NOTFOUND; 679 | } 680 | 681 | /*---------------------------------------------------------------------------*/ 682 | 683 | LK_RESULT _Lk_EvalArgs(wchar_t* invalidArg) { 684 | _LKTRACE("_Lk_EvalArgs\n"); 685 | LK_RESULT r = LK_R_OK; 686 | 687 | if (LK_R_OK != (r = _Lk_EvalGroups(invalidArg))) 688 | return r; 689 | 690 | if (LK_R_OK != (r = _Lk_MapNamedArgs())) 691 | return r; 692 | 693 | size_t i; 694 | LK_TOKEN_LIST_ENTRY* pTok = NULL; 695 | 696 | for (i = 0; i < _Lk_TokenGetCount(); i++) 697 | { 698 | _Lk_TokenGet(i, &pTok); 699 | 700 | if (pTok->item.memberOf != LK_NOGROUP && g_groupInfo[pTok->item.memberOf].selectedParam) 701 | { 702 | _LKTRACEW(L"_Lk_EvalArgs: IGNORING token %s: Member of group %d, but already got a parameter mapped\n", 703 | pTok->item.name, pTok->item.memberOf); 704 | continue; 705 | } 706 | 707 | switch (pTok->item.type) 708 | { 709 | case LK_TOKEN_TYPE_PARAMETER: 710 | 711 | if (_Lk_FindArgumentName(pTok->item.name, true) == LK_R_FALSE && !pTok->isOptional) 712 | { 713 | _LKTRACEW(L"_Lk_EvalArgs: Required argument NOT FOUND: %s\n", pTok->item.name); 714 | wcscpy_s(invalidArg, LK_MAX_TOKENARG_LEN, pTok->item.name); 715 | return LK_E_MISSINGARG; 716 | } 717 | 718 | break; 719 | 720 | case LK_TOKEN_TYPE_PARAMETER_VAL: 721 | 722 | if (_Lk_FindArgumentName(pTok->item.name, true) == LK_R_FALSE && !pTok->isOptional) 723 | { 724 | _LKTRACEW(L"_Lk_EvalArgs: Required argument NOT FOUND: %s\n", pTok->item.name); 725 | wcscpy_s(invalidArg, LK_MAX_TOKENARG_LEN, pTok->item.name); 726 | return LK_E_MISSINGARG; 727 | } 728 | 729 | if (!pTok->isOptional) 730 | { 731 | wchar_t* paramVal; 732 | if (_Lk_GetParamValue(pTok->item.name, ¶mVal) != LK_R_OK) 733 | { 734 | wcscpy_s(invalidArg, LK_MAX_TOKENARG_LEN, pTok->item.name); 735 | return LK_E_MISSINGVALUE; 736 | } 737 | } 738 | break; 739 | 740 | case LK_TOKEN_TYPE_PARAMETER_VAL_OPT: 741 | if (_Lk_FindArgumentName(pTok->item.name, true) == LK_R_FALSE && !pTok->isOptional) { 742 | _LKTRACEW(L"_Lk_EvalArgs: Required argument NOT FOUND: %s\n", pTok->item.name); 743 | wcscpy_s(invalidArg, LK_MAX_TOKENARG_LEN, pTok->item.name); 744 | return LK_E_MISSINGARG; 745 | } 746 | 747 | break; 748 | 749 | case LK_TOKEN_TYPE_NAMED_ARGUMENT: 750 | break; 751 | 752 | default: 753 | assert(false); 754 | break; 755 | } 756 | } 757 | 758 | 759 | if (_Lk_FindUnprocessedArg(invalidArg) == LK_R_TRUE) 760 | return LK_E_INVALIDARG; 761 | 762 | return LK_R_OK; 763 | } 764 | 765 | /*---------------------------------------------------------------------------*/ 766 | LK_RESULT _Lk_VerifyParamNames(wchar_t* invalidArg) { 767 | 768 | LK_TOKEN_LIST_ENTRY* pTok; 769 | bool fOk; 770 | 771 | for (size_t i = 0; i < g_argList.count; i++) { 772 | if (g_argList.item[i].name[0] == L'/') { 773 | fOk = false; 774 | for (size_t j = 0; j < _Lk_TokenGetCount(); j++) { 775 | _Lk_TokenGet(j, &pTok); 776 | 777 | if (pTok->item.type == LK_TOKEN_TYPE_PARAMETER || 778 | pTok->item.type == LK_TOKEN_TYPE_PARAMETER_VAL || 779 | pTok->item.type == LK_TOKEN_TYPE_PARAMETER_VAL_OPT) { 780 | if (! _wcsicmp(pTok->item.name, g_argList.item[i].name)) { 781 | fOk = true; 782 | break; 783 | } 784 | } 785 | } 786 | 787 | if (!fOk) { 788 | wcscpy_s(invalidArg, LK_MAX_TOKENARG_LEN, g_argList.item[i].name); 789 | return LK_E_INVALIDARG; 790 | } 791 | } 792 | } 793 | return LK_R_OK; 794 | } 795 | 796 | /*---------------------------------------------------------------------------*/ 797 | LK_RESULT _Lk_ValidateArgV(int argc, wchar_t** argv, wchar_t* invalidArg) 798 | { 799 | _LKTRACE("_Lk_ValidateArgV\n"); 800 | 801 | // Do first pass to arguments: verify duplicates, basic style, etc. 802 | // 803 | int i; 804 | size_t j; 805 | for (i = 1; i < argc; i++) 806 | { 807 | // Check if there are duplicates 808 | 809 | _LKTRACE(" Verifying duplicates...\n"); 810 | for (j = 0; j < g_argList.count; ++j) 811 | { 812 | if ( (_wcsicmp(argv[i], g_argList.item[j].name) == 0) 813 | &&(g_argList.item[j].name[0] == L'/')) 814 | { 815 | wcscpy_s(invalidArg, LK_MAX_TOKENARG_LEN, argv[i]); 816 | _LKTRACEW(L" Duplicate %s argument found\n", argv[i]); 817 | return LK_E_DUPLICATEARG; 818 | } 819 | } 820 | 821 | // If argument includes '=' or ':', strip value and parameter name 822 | if (argv[i][0] == L'/') 823 | { 824 | _LKTRACEW(L" %s: Parameter argument\n", argv[i]); 825 | wchar_t* delim = NULL; 826 | g_argList.item[j].isParam = true; 827 | 828 | if ( (delim = wcschr(argv[i], L':')) || 829 | (delim = wcschr(argv[i], L'=')) ) 830 | { 831 | if ( *(delim+1) == L'\0') // delimiter present but no value! 832 | { 833 | wcscpy_s(invalidArg, LK_MAX_TOKENARG_LEN, argv[i]); 834 | return LK_E_MISSINGVALUE; 835 | } 836 | else 837 | { 838 | if (wcslen(delim + 1) > LK_MAX_PARAMVALUE_LEN) 839 | { 840 | wcsncpy_s(invalidArg, LK_MAX_TOKENARG_LEN, argv[i], delim - argv[i]); 841 | return LK_E_VALUELENGTH; 842 | } 843 | 844 | wcsncpy_s(g_argList.item[j].name, LK_MAX_TOKENARG_LEN, argv[i], 845 | delim - argv[i]); 846 | wcscpy_s(g_argList.item[j].value, LK_MAX_PARAMVALUE_LEN, 847 | delim + 1); 848 | 849 | g_argList.item[j].hasValue = true; 850 | } 851 | } 852 | else 853 | { 854 | wcscpy_s(g_argList.item[j].name, LK_MAX_TOKENARG_LEN, argv[i]); 855 | g_argList.item[j].hasValue = false; 856 | } 857 | } 858 | else // non-parameter argument 859 | { 860 | _LKTRACEW(L" %s: Non-Parameter argument \n", argv[i]); 861 | g_argList.item[j].isParam = false; 862 | g_argList.item[j].hasValue = true; 863 | wcscpy_s(g_argList.item[j].value, LK_MAX_PARAMVALUE_LEN, argv[i]); 864 | wcscpy_s(g_argList.item[j].name, LK_MAX_TOKENARG_LEN, LK_UNMAPPED_ARG_NAME); 865 | } 866 | 867 | g_argList.item[j].matchingGroup = LK_NOGROUP; 868 | g_argList.item[j].isMapped = false; 869 | g_argList.item[j].isProcessed = false; 870 | g_argList.count = j+1; 871 | } 872 | return LK_R_OK; 873 | } 874 | 875 | void _Lk_StoreExtErr(LK_RESULT e, const wchar_t* arg) 876 | { 877 | for (size_t i = 0; i < LK_ARRAYSIZE(g_lkErrTable); ++i) 878 | { 879 | if (g_lkErrTable[i].res == e) { 880 | if (arg) 881 | swprintf(g_exErrBuffer, LK_MAX_ERRORBUFFER_LEN, g_lkErrTable[i].wErrMsg, arg); 882 | else 883 | wcscpy_s(g_exErrBuffer, LK_MAX_ERRORBUFFER_LEN, g_lkErrTable[i].wErrMsg); 884 | 885 | return; 886 | } 887 | } 888 | 889 | wcscpy_s(g_exErrBuffer, LK_MAX_ERRORBUFFER_LEN, L"Undefined error"); 890 | } 891 | 892 | /****************************************************************************** 893 | 894 | Public API begins here 895 | 896 | ***************************************************************************/ 897 | 898 | /*---------------------------------------------------------------------------*/ 899 | LK_RESULT LkInit() 900 | { 901 | LK_RESULT r = _Lk_TokenListInit(LK_MAX_TOKENARG_COUNT); 902 | LK_RETURN_STERR(r); 903 | } 904 | 905 | /*---------------------------------------------------------------------------*/ 906 | LK_RESULT LkFree(void) 907 | { 908 | _Lk_TokenListFree(); 909 | LK_RETURN_STERR(LK_R_OK); 910 | } 911 | 912 | 913 | /* --------------------------------------------------------------------------- 914 | Sets the syntax for the command-line to be validated against. 915 | 916 | syntax: The syntax specification string, with tokens separated by 917 | spaces. 918 | invalidToken: A pointer to a character array to store the token that 919 | caused an error, if it can be determined. 920 | cchBuf: The size of the invalidArg buffer, in characters. Must 921 | be >= LK_MAX_TOKENARG_LEN. 922 | 923 | Returns: LK_R_OK if successful. 924 | LK_E_MALLOC if memory allocation error occurred. 925 | LK_E_TOKENCOUNT if number of specified token exceeds the constant 926 | LK_MAX_TOKENARG_COUNT. 927 | LK_E_UNINITIALIZED if library is not initialized yet. 928 | LK_E_NULLPOINTER if NULL pointer is passed in call. 929 | LK_E_INVALIDSYNTAX if syntax string is not allowed. 930 | 931 | Other error codes can be returned. (See LK_RESULT) 932 | 933 | --------------------------------------------------------------------------*/ 934 | LK_RESULT LkSetSyntax(const wchar_t* syntax, wchar_t* invalidToken, size_t cchBuf) 935 | { 936 | _LKTRACE("_Lk_SetSyntax\n"); 937 | 938 | if (cchBuf < LK_MAX_TOKENARG_LEN) 939 | LK_RETURN_STERR(LK_E_INSUFFICIENTBUFFER); 940 | 941 | if (!g_tokenList) 942 | LK_RETURN_STERR(LK_E_UNINITIALIZED); 943 | if (!syntax || !invalidToken) 944 | LK_RETURN_STERR(LK_E_NULLPOINTER); 945 | 946 | _Lk_TokenListClear(); 947 | 948 | g_syntaxValid = true; 949 | g_tokenCount = 0; 950 | g_groupCount = 0; 951 | 952 | LK_RESULT res; 953 | int i = 0; 954 | int iTokStart = 0; 955 | while(1) 956 | { 957 | if (syntax[i] == L' ' || syntax[i] == L'\0') 958 | { 959 | size_t cbToken = sizeof(wchar_t) * (i - iTokStart); 960 | 961 | if (cbToken > LK_MAX_TOKENARG_LEN * sizeof(wchar_t)) 962 | LK_RETURN_STERR(LK_E_TOKENLENGTH); 963 | 964 | wchar_t* token = (wchar_t * )malloc(cbToken + sizeof(wchar_t)); 965 | if (!token) 966 | LK_RETURN_STERR(LK_E_MALLOC); 967 | 968 | memcpy(token, syntax + iTokStart, cbToken); 969 | token[cbToken/sizeof(wchar_t)] = L'\0'; 970 | res = _Lk_ClassifyToken(token); 971 | if (LK_SUCCESS(res)){ 972 | free(token); 973 | } 974 | else 975 | { 976 | _LKTRACEW(L" Token classification fail (%s) (0x%08x)\n", token, res); 977 | g_syntaxValid = false; 978 | wcscpy_s(invalidToken, LK_MAX_TOKENARG_LEN, token); 979 | return res; 980 | } 981 | if (syntax[i] == L'\0') 982 | break; 983 | 984 | while (syntax[++i] == L' '); /* Ignore multiple spaces */ 985 | iTokStart = i; 986 | 987 | if (g_tokenCount == LK_MAX_TOKENARG_COUNT) 988 | LK_RETURN_STERR(LK_E_TOKENCOUNT); 989 | } 990 | else 991 | i++; 992 | }; 993 | 994 | _LKTRACEW(L" Function successful\n"); 995 | LK_RETURN_STERR(LK_R_OK); 996 | } 997 | 998 | /* --------------------------------------------------------------------------- 999 | Returns if the specified parameter or named-argument is present. 1000 | 1001 | paramName: The command line parameter or named-argument to query. 1002 | 1003 | Returns: LK_R_OK if successful. 1004 | LK_E_NOTFOUND if parameter does not exist. 1005 | --------------------------------------------------------------------------*/ 1006 | LK_RESULT LkIsParamPresent(const wchar_t* paramName) 1007 | { 1008 | if (!paramName || !wcslen(paramName)) 1009 | return (LK_E_INVALIDARG); 1010 | 1011 | size_t i; 1012 | for (i = 0; i < g_argList.count; ++i) 1013 | if (!_wcsicmp(paramName, g_argList.item[i].name)) 1014 | return (LK_R_OK); 1015 | 1016 | return (LK_E_NOTFOUND); 1017 | } 1018 | 1019 | /* --------------------------------------------------------------------------- 1020 | Returns the specified parameter or named-argument value. 1021 | 1022 | paramName: The command line parameter or named-argument to query. 1023 | paramValue: A pointer to a character array to store the returned value. 1024 | 1025 | Returns: LK_R_OK if successful. 1026 | LK_E_UNDEFINED if no value was specified on the command-line. 1027 | LK_E_NOTFOUND if parameter or named-argument does not exist. 1028 | 1029 | Remarks: 1030 | 1031 | - If return value is not LK_R_OK, *paramValue will be set to NULL. 1032 | - The caller *must not free* the returned pointer. 1033 | --------------------------------------------------------------------------*/ 1034 | LK_RESULT LkGetParamValue(const wchar_t* paramName, wchar_t** paramValue) { 1035 | LK_RESULT r = _Lk_GetParamValue(paramName, paramValue); 1036 | return r; 1037 | } 1038 | 1039 | /* --------------------------------------------------------------------------- 1040 | Parses the specified command-line. 1041 | 1042 | argc: The argument count. 1043 | argv: The array of arguments in the command line. 1044 | invalidArg: A character array to store the argument that 1045 | is causing a parsing error, if it can be determined. 1046 | cchBuf: The size of the invalidArg buffer, in characters. Must 1047 | be >= LK_MAX_TOKENARG_LEN. 1048 | 1049 | Returns: LK_R_OK if successful. 1050 | LK_E_INVALIDSYNTAX if syntax to be parsed in invalid. 1051 | --------------------------------------------------------------------------*/ 1052 | LK_RESULT LkParse(int argc, wchar_t** argv, wchar_t* invalidArg, size_t cchBuf) 1053 | { 1054 | if (cchBuf < LK_MAX_TOKENARG_LEN) 1055 | LK_RETURN_STERR(LK_E_INSUFFICIENTBUFFER); 1056 | 1057 | g_argList.count = 0; 1058 | 1059 | if (!g_syntaxValid) 1060 | LK_RETURN_STERR(LK_E_INVALIDSYNTAX); 1061 | 1062 | LK_RESULT r = _Lk_ValidateArgV(argc, argv, invalidArg); 1063 | 1064 | if (LK_SUCCESS(r)) 1065 | r = _Lk_VerifyParamNames(invalidArg); 1066 | 1067 | if (LK_SUCCESS(r)) 1068 | r = _Lk_EvalArgs(invalidArg); 1069 | 1070 | LK_RETURN_STERR1(r,invalidArg); 1071 | } 1072 | 1073 | /* --------------------------------------------------------------------------- 1074 | Parses the specified command-line. 1075 | 1076 | commandLine: The command-line to parse. 1077 | invalidArg: A character array to store the argument that 1078 | is causing a parsing error, if it can be determined. 1079 | cchBuf: The size of the invalidArg buffer, in characters. Must 1080 | be >= LK_MAX_TOKENARG_LEN. 1081 | 1082 | Returns: LK_R_OK if successful. 1083 | LK_E_INVALIDSYNTAX if syntax to be parsed is invalid. 1084 | --------------------------------------------------------------------------*/ 1085 | LK_RESULT LkParse2(wchar_t* commandLine, wchar_t* invalidArg, size_t cchBuf) 1086 | { 1087 | if (cchBuf < LK_MAX_TOKENARG_LEN) 1088 | LK_RETURN_STERR(LK_E_INSUFFICIENTBUFFER); 1089 | 1090 | if (!g_syntaxValid) 1091 | LK_RETURN_STERR(LK_E_INVALIDSYNTAX); 1092 | if (!commandLine) 1093 | LK_RETURN_STERR(LK_E_INVALIDARG); 1094 | 1095 | wchar_t* wCmdLineBuf = _wcsdup(commandLine); 1096 | if (!wCmdLineBuf) 1097 | LK_RETURN_STERR(LK_E_MALLOC); 1098 | 1099 | wchar_t* buf = NULL; 1100 | wchar_t* thisarg = wcstok_s(wCmdLineBuf, L" ", &buf); 1101 | wchar_t* argv[LK_MAX_TOKENARG_COUNT]; 1102 | argv[0] = L"DUMMY.EXE"; //this wont be used 1103 | int argc = 1; 1104 | while (thisarg != NULL && argc < LK_MAX_TOKENARG_COUNT) 1105 | { 1106 | argv[argc++] = thisarg; 1107 | thisarg = wcstok_s(NULL, L" ", &buf); 1108 | } 1109 | 1110 | LK_RESULT r = LkParse(argc, argv, invalidArg, cchBuf); 1111 | free(wCmdLineBuf); 1112 | 1113 | LK_RETURN_STERR1(r,invalidArg); 1114 | } 1115 | 1116 | /* --------------------------------------------------------------------------- 1117 | Returns the extended error message for the last operation. 1118 | --------------------------------------------------------------------------*/ 1119 | const wchar_t* const LkGetExtErrorString() { 1120 | return g_exErrBuffer; 1121 | } 1122 | 1123 | /*-----------------------------------------------------------------------------*/ 1124 | 1125 | #ifdef __cplusplus 1126 | } 1127 | #endif 1128 | 1129 | #endif // __LINKOM_H__f82e85a35f914826a6af35aa02839625 1130 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Linkom 2 | **A single-header, command-line parser library in C** 3 | 4 | _With a quick-and-dirty COM wrapper for multi-language support_ 5 | 6 | ## License Terms 7 | 8 | Linkom Library 9 | Copyright (c) 2016 Hernán Di Pietro 10 | 11 | Wide-char safe string functions 12 | Copyright 1999 Alexandre Julliard 13 | Copyright 2000 Jon Griffiths 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | 33 | ## Introduction 34 | 35 | Linkom is a single-header, command-line parser library written in C. The language and distribution decision was based on the fact that A LOT of command line utilities are still being written in C (and not just C++). 36 | 37 | For programmers using other languages than C/C++, a COM component wrapper is provided. See below for info. 38 | 39 | Note that the symbols and jargon that the library and it's documentation use, such as "/" character for parameters and { } for grouping them, is based on the classic DOS/CPM/Microsoft documentation style. This is different from the UNIX/Linux and GNU tradition where '--' and "options" are used instead. 40 | 41 | In the future, the library *could* support varying "symbolisms" to handle different styles. 42 | 43 | ## A note about why wchar_t 44 | 45 | As Linkom was developed at first for homebrew Windows platform projects, the character arrays and functions used are `wchar_t` based. A conversion to `char`-based, UTF8 strings, maybe interesting to implement. 46 | 47 | ## Terminology 48 | 49 | The following conventions in this library and it's documentation. 50 | 51 | **Syntax** is the string the command-line will be validated against by the parser. 52 | 53 | **Token** is a component in the *Syntax* string, delimited by spaces. 54 | 55 | **Argument** is the component in which a command-line is separated into. 56 | 57 | **Parameter** is an argument starting with '/' and that may carry a value after ':' or '=' character. This is the analog of the UNIX "option". 58 | 59 | ## Building the library 60 | 61 | *Linkom* is a single-header library containing C code, so it does not require building any LIB or DLL file to be used; any reasonably modern C compiler should handle it. The file TESTRUN.C is included for development and testing purposes, it will execute several tests and report which of them failed. 62 | 63 | The library successfully builds and passes tests on: 64 | 65 | * Microsoft Visual C++ 2015 66 | * Microsoft Visual C++ 2012 67 | * GCC 6.2.0 68 | * clang 3.8.1 69 | 70 | 71 | ## Using the library 72 | 73 | You can include the library code by just inserting 74 | 75 | #include "linkom.h" 76 | 77 | at the top of your desired C/C++ source file. 78 | 79 | All the public API functions return an unsigned integer value from the `LK_RESULT` enumeration (see the header file for reference). You can use the `LK_SUCCESS` macro to test for the `LK_R_OK` value. 80 | 81 | Let's continue looking at typical usage examples. 82 | 83 | ### Initialization and shutdown 84 | 85 | Before anything, you should initialize the library with `LkInit`. To shutdown, call `LkFree` to free used memory resources. 86 | 87 | /* Ex 1: Initialization and shutdown */ 88 | 89 | LK_RESULT r = LkInit(); 90 | if (r != LK_R_OK) 91 | { 92 | printf ("Initialization error"); 93 | exit(EXIT_FAILURE); 94 | } 95 | 96 | // ... 97 | // use library here 98 | // ... 99 | 100 | 101 | LkFree(); 102 | 103 | ### Basic command line parsing 104 | 105 | The basic procedure to work with a command line string is to stablish a syntax for the parser to work against first, and call the parser itself with a command-line which will return a successful return value if the command-line is compliant with the syntax specification. 106 | 107 | /* Ex 2: Parsing a command line, basic example 108 | 109 | wchar_t invToken[256], invArg[256]; 110 | LK_RESULT r = LkSetSyntax(L"$filename", invToken, _countof(invToken))); 111 | if (r == LK_R_OK) 112 | { 113 | r = LkParse(argc, argv, invArg, _countof(invArg)); 114 | if (r == LK_R_OK) 115 | { 116 | // Work with args... 117 | } 118 | } 119 | 120 | The syntax specification says that we'll accept any command line with one named argument (`$filename`) that may be present or not. Named arguments, preceded with the `$` prefix, are mapped 1-to-1 to the arguments found in 121 | the command line specified at the `LkParse` call. 122 | 123 | Use spaces between syntax tokens: `$a $b` is allowed while `$a$b` is not. 124 | 125 | The second parameter of `LkSetSyntax`, as well as the third of `LkParse`, must supply a pointer to a buffer with a minimum of `LK_MAX_TOKENARG_LEN` characters. If the function fails, this buffer will be filled with the token or parameter where the syntax evaluation or parsing stopped due to error. 126 | 127 | You can get the argument mapped using the `LkGetParamValue` function, as follows: 128 | 129 | wchar_t* file; 130 | LkGetParamValue (L"$filename", &file); 131 | if (file) 132 | { 133 | printf("Provided filename: %S", file); 134 | } 135 | 136 | Now suppose the following syntax spec: 137 | 138 | LkSetSyntax(L"$a $b $c $d", invToken, _countof(invToken))); 139 | 140 | This will assign each argument from the command line to each syntax token ($a...$d) in order. 141 | 142 | ### Using parameters 143 | 144 | In addition of named-parameters, standard parameter tokens beginning with `/` can be used in the syntax-specification with varying forms. First, any parameter enclosed with brackets `[ ]` will make it optional. Second, a parameter may ask for a value (which can be also optional), using `=` or `?` character suffixes. Briefly, 145 | 146 | * `/X` token specifies a required parameter. 147 | * `/FILE=` token specifies a required parameter and value (e.g: a valid command line argument to match could be `/FILE=readme.txt` or `/FILE:copy.com`) 148 | * `/SYS?` token specifies a required parameter and an optional value (valid command line arguments to match could be `/SYS=unix`, `/SYS:win` or `SYS`)). 149 | 150 | Enclosing the above parameters with `[ ]` will make them optional. 151 | 152 | ### Exclusive parameter groups 153 | 154 | Enclosing a set of parameters with braces `{ }` ,separated by `|` allows to enforce the use of one parameter at maximum from the group. If two or more parameters from the same group are on the command line string, the parser will fail. Let's see an example: 155 | 156 | LkSetSyntax(L"{/x|/y|/z}", invToken, _countof(invToken))); 157 | 158 | With the above syntax specification, parsing "/x" "/y" or "/z" will succeed, but "/x /y" or "/z /x" will not. 159 | A group token can be optional and the parameter themselves can be valued parameters or optionally-valued parameters, as in 160 | 161 | LkSetSyntax(L"{/x|/y} [{/a?|b=|/c}]", invToken, _countof(invToken))); 162 | 163 | From this syntax spec, `/x /a:1` `/y /a` or `/x` will be parsed successfully. 164 | 165 | Note that *named-arguments are not supported within groups*. 166 | 167 | ### Error messages facility 168 | 169 | The library can facilitate handling the printing of all or a subset of error conditions during parsing phase using the 170 | `LkGetExtErrorString` function, which will print a descriptive message along with (optional) information about the source of the conflict. 171 | 172 | Suppose the following syntax specification: 173 | 174 | `{/A|/B}` 175 | 176 | Parsing the command line `/A /B` against that syntax will make the `LkParse` call to return with the `LK_E_CONTRADICTARG` value, with the last character array argument of `LkParse` filled with the arguments in conflict. To inform the user you could simply call e.g: 177 | 178 | 179 | if (r != LK_R_OK) { 180 | _putws(LkGetExtErrorString()); 181 | return -1; 182 | } 183 | 184 | The above example will print: 185 | 186 | `Contradictory arguments: /A /B` 187 | 188 | See the header file for the message-table, which you can localize (I18N) to suit your needs. 189 | 190 | ## ATL/COM Component 191 | 192 | To allow the library to be used in languages with COM binding support, you can build an ATL/COM project under the COM directory; after the build succeeds, register the library traditionally (see the output directory, which depends on Debug/release mode and 32/64 bit architecture). 193 | 194 | REM Do this elevated 195 | regsvr32 linkom_atl.dll 196 | 197 | With your preferred development environment, bind your project/source to the Linkom_atl DLL, or the Linkom.1 ProgID. See your language/IDE/Platform manual/reference for guidelines on how to bind to COM objects. 198 | 199 | ## FAQ 200 | 201 | * Q: Are arrays of strings supported "automagically"? e.g: passing one or more filenames in the command-line. 202 | 203 | * A: There is no provided support. You can handle it by using a named argument or a parameter with a value, for example the following syntax specifications are an example: 204 | 205 | LkSetSyntax(L"/files=", invToken, _countof(invToken))); 206 | LkSetSyntax(L"$filenamelist", invToken, _countof(invToken))); 207 | 208 | where the following would be acceptable command-lines to match: `/FILES=1.txt,2.txt,3.txt,4.txt` and `1.txt;2.exe;3.pif;4.com` respectively. 209 | 210 | In each case you should handle the comma-delimited list yourself after getting value: 211 | 212 | LkGetParamValue(L"$filenamelist", wFileList); 213 | if ( wFileList ) 214 | // parse command-delimited value... 215 | 216 | 217 | 218 | -------------------------------------------------------------------------------- /samples/c/emulfake.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hernandp/linkom/53609c48d4813e957ab31b42de53f85c29c45bcc/samples/c/emulfake.c -------------------------------------------------------------------------------- /samples/cs/EmulFakeCS/EmulFakeCS.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B8B7210F-28E0-4BCD-80F1-B61694EE77A0} 8 | Exe 9 | Properties 10 | EmulFakeCS 11 | EmulFakeCS 12 | v3.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | {C61FE5D4-6F4E-4693-A707-3AB2B1DD4F89} 49 | 1 50 | 0 51 | 0 52 | tlbimp 53 | False 54 | True 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /samples/cs/EmulFakeCS/EmulFakeCS.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmulFakeCS", "EmulFakeCS.csproj", "{B8B7210F-28E0-4BCD-80F1-B61694EE77A0}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B8B7210F-28E0-4BCD-80F1-B61694EE77A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {B8B7210F-28E0-4BCD-80F1-B61694EE77A0}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {B8B7210F-28E0-4BCD-80F1-B61694EE77A0}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {B8B7210F-28E0-4BCD-80F1-B61694EE77A0}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /samples/cs/EmulFakeCS/Program.cs: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This file is part of Linkom Library 4 | 5 | Copyright (c) 2016 Hernán Di Pietro 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | */ 23 | 24 | using System; 25 | using System.Collections.Generic; 26 | using System.Linq; 27 | using System.Text; 28 | 29 | namespace EmulFakeCS 30 | { 31 | class Program 32 | { 33 | static void Main(string[] args) 34 | { 35 | Linkom.ILinkom linkom = new Linkom.Linkom(); 36 | string invToken; 37 | string invArg; 38 | if (args.Length == 0) 39 | { 40 | ShowUsage(); 41 | return; 42 | } 43 | try 44 | { 45 | linkom.SetSyntax("[/?] /DISK0= /RAM= /CACHE? [/DD?] [/DISK1=] [/FAST] [{/ALTCPU1|/ALTCPU2}] {/CGA|/EGA|/VGA|/MCGA} $biosrom $firmware0rom", out invToken); 46 | linkom.Parse(string.Join(" ", args), out invArg); 47 | } 48 | catch 49 | { 50 | Console.WriteLine(linkom.GetExtErrorString()); 51 | return; 52 | } 53 | 54 | if (linkom.IsParamPresent("/?") == 0) 55 | { 56 | ShowUsage(); 57 | return; 58 | } 59 | 60 | string BIOSROM = null, FirmwareROM = null; 61 | try 62 | { 63 | linkom.GetParamValue("$biosrom", out BIOSROM); 64 | linkom.GetParamValue("$firmware0rom", out FirmwareROM); 65 | } 66 | catch 67 | { 68 | if (BIOSROM == null) 69 | Console.WriteLine("WARNING: Please provide a BIOS ROM name."); 70 | 71 | if (FirmwareROM == null) 72 | Console.WriteLine("WARNING: Please provide a BIOS ROM name."); 73 | } 74 | 75 | 76 | 77 | 78 | System.Console.ReadKey(); 79 | } 80 | 81 | private static void ShowUsage() 82 | { 83 | throw new NotImplementedException(); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /samples/cs/EmulFakeCS/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("EmulFakeCS")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("EmulFakeCS")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b8b7210f-28e0-4bcd-80f1-b61694ee77a0")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /testrun.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This file is part of Linkom Library 4 | 5 | Copyright (c) 2016 Hernán Di Pietro 6 | 7 | Widechar safe string functions 8 | Copyright 1999 Alexandre Julliard 9 | Copyright 2000 Jon Griffiths 10 | 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in all 20 | copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | SOFTWARE. 29 | 30 | */ 31 | 32 | #define LK_DEFINE_USER_LIMITS 33 | #define LK_MAX_TOKENARG_LEN 16 /* Maximum argument and token length */ 34 | #define LK_MAX_TOKENARG_COUNT 8 /* Maximum argument and token count */ 35 | #define LK_MAX_GROUP_COUNT 3 /* Maximum group count */ 36 | #define LK_MAX_GR_MEMBERS_COUNT 4 /* Maximum members per group count */ 37 | #define LK_MAX_PARAMVALUE_LEN 16 /* Max str length for param. values*/ 38 | //#define LK_ENABLE_TRACE 39 | #include "linkom.h" 40 | 41 | #define TESTINIT() int _testc = 0; int _testok = 0; bool _r; 42 | #define VERIFY(_expr) _testc++;printf("%s " #_expr "\n",( _r = (_expr)) ? "[ OK ]":"[FAIL]"); if(_r) _testok++; 43 | #define TESTEND printf("\nTest results: %d executed, %d successful, %d failed\n", _testc, _testok, _testc - _testok); 44 | 45 | int main(int argc, char** argv) 46 | { 47 | TESTINIT(); 48 | wchar_t invToken[LK_MAX_TOKENARG_LEN]; 49 | wchar_t invArg[LK_MAX_TOKENARG_LEN]; 50 | wchar_t* val = NULL; 51 | 52 | printf("-------- Initialization -------------------------------------- \n"); 53 | VERIFY(LK_SUCCESS(LkInit())); 54 | 55 | printf("-------- Boundary checks ------------------------------------- \n"); 56 | VERIFY(LkParse2(L"Parsing_without_syntax", invToken, LK_MAX_TOKENARG_LEN) == LK_E_INVALIDSYNTAX); 57 | VERIFY(LkSetSyntax(L"[/A] [/XXXXXXXXXXXXXXXXXXXXXXX]", invToken, LK_MAX_TOKENARG_LEN) == LK_E_TOKENLENGTH); 58 | VERIFY(LkSetSyntax(L"[/0] [/1] [/2] [/3] [/4] [/5] [/6] [/7] [/8]", invToken, LK_MAX_TOKENARG_LEN) == LK_E_TOKENCOUNT); 59 | VERIFY(LkSetSyntax(L"{/a|/b} {/c|/d} {/e|/f} {/g|/h}", invToken, LK_MAX_TOKENARG_LEN) == LK_E_GROUPCOUNT); 60 | VERIFY(LkSetSyntax(L"[/A=]", invToken, LK_MAX_TOKENARG_LEN) == LK_R_OK); 61 | VERIFY(LkParse2(L"/A=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",invArg, LK_MAX_TOKENARG_LEN) == LK_E_VALUELENGTH); 62 | 63 | printf("-------- Basic checks -------------------------------------- \n"); 64 | 65 | VERIFY(LkSetSyntax(L"[/A] [/B] [/C]", invToken, LK_MAX_TOKENARG_LEN) == LK_R_OK); 66 | VERIFY(LkSetSyntax(L"[/A] [C*", invToken, LK_MAX_TOKENARG_LEN) == LK_E_INVALIDSYNTAX); 67 | VERIFY(invToken != NULL && !wcscmp(invToken,L"[C*")); 68 | VERIFY(LkSetSyntax(L"[/B] [/B]", invToken, LK_MAX_TOKENARG_LEN) == LK_E_DUPLICATETOKEN); 69 | VERIFY(LkSetSyntax(L"[/A] [/B]", invToken, LK_MAX_TOKENARG_LEN) == LK_R_OK); 70 | 71 | VERIFY(LkParse2(L"", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 72 | VERIFY(LkParse2(L"/A", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 73 | VERIFY(LkParse2(L"/B", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 74 | VERIFY(LkParse2(L"/A /B", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 75 | VERIFY(LkParse2(L"/B /A", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 76 | VERIFY(LkParse2(L"/B /B", invArg, LK_MAX_TOKENARG_LEN) == LK_E_DUPLICATEARG); 77 | VERIFY(invArg != NULL && !wcscmp(invArg, L"/B")); 78 | VERIFY(LkParse2(L"/Z", invArg, LK_MAX_TOKENARG_LEN) == LK_E_INVALIDARG); 79 | VERIFY(invArg != NULL && !wcscmp(invArg, L"/Z")); 80 | 81 | printf("-------- Optional arguments check -------------------------- \n"); 82 | VERIFY(LkSetSyntax(L"/A [/B]", invToken, LK_MAX_TOKENARG_LEN) == LK_R_OK); 83 | VERIFY(LkParse2(L"", invArg, LK_MAX_TOKENARG_LEN) == LK_E_MISSINGARG); 84 | VERIFY(invArg != NULL && !wcscmp(invArg, L"/A")); 85 | VERIFY(LkParse2(L"/C", invArg, LK_MAX_TOKENARG_LEN) == LK_E_INVALIDARG); 86 | VERIFY(invArg != NULL && !wcscmp(invArg, L"/C")); 87 | VERIFY(LkParse2(L"/A /C", invArg, LK_MAX_TOKENARG_LEN) == LK_E_INVALIDARG); 88 | VERIFY(invArg != NULL && !wcscmp(invArg, L"/C")); 89 | VERIFY(LkParse2(L"/A", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 90 | VERIFY(LkParse2(L"/A /B", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 91 | VERIFY(LkParse2(L"/B /A", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 92 | 93 | printf("-------- Valued parameters check ---------------------------- \n"); 94 | 95 | VERIFY(LkSetSyntax(L"/A= /B? [/C]", invToken, LK_MAX_TOKENARG_LEN) == LK_R_OK); 96 | VERIFY(LkParse2(L"/A=2 /B=", invArg, LK_MAX_TOKENARG_LEN) == LK_E_MISSINGVALUE); 97 | VERIFY(invArg != NULL && !wcscmp(invArg, L"/B=")); 98 | VERIFY(LkParse2(L"/A=1 /B=xyz /C", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 99 | VERIFY(LkGetParamValue(L"/C", &val) == LK_E_UNDEFINED); 100 | VERIFY(LkParse2(L"/A=1 /B", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 101 | VERIFY(LkParse2(L"/A", invArg, LK_MAX_TOKENARG_LEN) == LK_E_MISSINGVALUE); 102 | VERIFY(invArg != NULL && !wcscmp(invArg, L"/A")); 103 | VERIFY(LkGetParamValue(L"/C", &val) == LK_E_NOTFOUND); 104 | VERIFY(LkParse2(L"/A=1 /C", invArg, LK_MAX_TOKENARG_LEN) == LK_E_MISSINGARG); 105 | VERIFY(LkParse2(L"/A=1 /B=xyz", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 106 | VERIFY(LkIsParamPresent(L"/A") == LK_R_OK); 107 | VERIFY(LkIsParamPresent(L"/B") == LK_R_OK); 108 | VERIFY(LkIsParamPresent(L"/X") == LK_E_NOTFOUND); 109 | VERIFY(LkGetParamValue(L"/A", &val) == LK_R_OK); 110 | VERIFY(val != NULL && !wcscmp (val, L"1")); 111 | VERIFY(LkGetParamValue(L"/B", &val) == LK_R_OK); 112 | VERIFY(val != NULL && !wcscmp (val, L"xyz")); 113 | VERIFY(LkGetParamValue(L"/D", &val) == LK_E_NOTFOUND); 114 | 115 | printf("-------- Named arguments check ------------------------------- \n"); 116 | VERIFY(LkSetSyntax(L"$file [$a] $b $c", invToken, LK_MAX_TOKENARG_LEN)== LK_E_INVALIDSYNTAX); 117 | VERIFY(LkSetSyntax(L"$file $a $b $c", invToken, LK_MAX_TOKENARG_LEN) == LK_R_OK); 118 | VERIFY(LkParse2(L"test.txt 1 2 3", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 119 | VERIFY(LkGetParamValue(L"$file", &val) == LK_R_OK); 120 | VERIFY(val != NULL && !wcscmp (val, L"test.txt")); 121 | VERIFY(LkParse2(L"test.txt 1 2", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 122 | VERIFY(LkParse2(L"z z z", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 123 | 124 | printf("--- Named arguments check (getting values) ------------------- \n"); 125 | VERIFY(LkParse2(L"test.txt 1", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 126 | VERIFY(LkGetParamValue(L"$file", &val) == LK_R_OK); 127 | VERIFY(val != NULL && !wcscmp (val, L"test.txt")); 128 | VERIFY(LkGetParamValue(L"$a", &val) == LK_R_OK); 129 | VERIFY(val != NULL && !wcscmp (val, L"1")); 130 | VERIFY(LkGetParamValue(L"$b", &val) == LK_E_NOTFOUND); 131 | VERIFY(LkGetParamValue(L"$c", &val) == LK_E_NOTFOUND); 132 | 133 | printf("--- Named arguments check (count exceeded) ------------------- \n"); 134 | VERIFY(LkParse2(L"test.txt 1 2 3 4 5 6 7 8 9", invArg, LK_MAX_TOKENARG_LEN) == LK_E_INVALIDARG); 135 | VERIFY(invArg != NULL && !wcscmp (invArg, L"4")); 136 | 137 | printf("--- group argument test -------------------------------------- \n"); 138 | VERIFY(LkSetSyntax(L"{x}", invToken, LK_MAX_TOKENARG_LEN)== LK_E_INVALIDSYNTAX); 139 | VERIFY(invToken != NULL && !wcscmp (invToken, L"{x}")); 140 | VERIFY(LkSetSyntax(L"{/x}", invToken, LK_MAX_TOKENARG_LEN)== LK_E_INVALIDSYNTAX); 141 | VERIFY(invToken != NULL && !wcscmp (invToken, L"{/x}")); 142 | VERIFY(LkSetSyntax(L"{/x|}", invToken, LK_MAX_TOKENARG_LEN)== LK_E_INVALIDSYNTAX); 143 | VERIFY(invToken != NULL && !wcscmp (invToken, L"{/x|}")); 144 | VERIFY(LkSetSyntax(L"{/on|/off} {/on|/x}", invToken, LK_MAX_TOKENARG_LEN) == LK_E_DUPLICATEGROUPITEM); 145 | VERIFY(LkSetSyntax(L"{/on|/off|/auto}", invToken, LK_MAX_TOKENARG_LEN) == LK_R_OK); 146 | VERIFY(LkParse2(L"/on", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 147 | VERIFY(LkParse2(L"/off", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 148 | VERIFY(LkParse2(L"/auto", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 149 | VERIFY(LkParse2(L"/auto /on", invArg, LK_MAX_TOKENARG_LEN) == LK_E_CONTRADICTARG); 150 | VERIFY(LkParse2(L"/auto /off", invArg, LK_MAX_TOKENARG_LEN) == LK_E_CONTRADICTARG); 151 | VERIFY(LkParse2(L"/on /off", invArg, LK_MAX_TOKENARG_LEN) == LK_E_CONTRADICTARG); 152 | 153 | VERIFY(LkSetSyntax(L"{/on|/off|/auto} {/x|/y|/z} {/a|/b}", invToken, LK_MAX_TOKENARG_LEN) == LK_R_OK); 154 | VERIFY(LkParse2(L"/on /a", invArg, LK_MAX_TOKENARG_LEN) == LK_E_NOGROUPMEMBERCHOSEN); 155 | VERIFY(LkParse2(L"/b /z /off", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 156 | VERIFY(LkParse2(L"/b /z /off /y", invArg, LK_MAX_TOKENARG_LEN) == LK_E_CONTRADICTARG); 157 | 158 | VERIFY(LkSetSyntax(L"{/on|/off|/auto} [{/x?|/y|/z}] {/a=|/b}", invToken, LK_MAX_TOKENARG_LEN) == LK_R_OK); 159 | VERIFY(LkParse2(L"/on", invArg, LK_MAX_TOKENARG_LEN) == LK_E_NOGROUPMEMBERCHOSEN); 160 | VERIFY(LkParse2(L"/on /b", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 161 | VERIFY(LkParse2(L"/on /a", invArg, LK_MAX_TOKENARG_LEN) == LK_E_MISSINGVALUE); 162 | VERIFY(LkParse2(L"/on /a=1000", invArg, LK_MAX_TOKENARG_LEN) == LK_R_OK); 163 | VERIFY(LkGetParamValue(L"/a", &val) == LK_R_OK); 164 | VERIFY(val != NULL && !wcscmp(val, L"1000")); 165 | 166 | VERIFY(LkSetSyntax(L"[{/help|/?}] [/fat=] /size= /boot= /media= [/lic] $file", invToken, LK_MAX_TOKENARG_LEN) == LK_R_OK); 167 | VERIFY(LkParse2(L"xxx", invArg, LK_MAX_TOKENARG_LEN) == LK_E_MISSINGARG); 168 | VERIFY(LkGetParamValue(L"$file", &val) == LK_R_OK); 169 | VERIFY(LkParse2(L"/zzzz", invArg, LK_MAX_TOKENARG_LEN) == LK_E_INVALIDARG); 170 | VERIFY(val != NULL && !wcscmp(val, L"xxx")); 171 | 172 | printf("--- Shutdown ------------------------------------------------- \n"); 173 | 174 | VERIFY(LK_SUCCESS(LkFree())); 175 | TESTEND; 176 | } 177 | 178 | static void Interactive(void) 179 | { 180 | TESTINIT(); 181 | VERIFY(LK_SUCCESS(LkInit())); 182 | wchar_t syntax[1024]; 183 | wchar_t cmdline[1024]; 184 | wchar_t invToken[LK_MAX_TOKENARG_LEN]; 185 | printf("\nsyntax? "); 186 | fgetws (syntax, 1024, stdin); 187 | syntax[wcscspn(syntax, L"\n")] = L'\0'; 188 | 189 | LK_RESULT r; 190 | if (!LK_SUCCESS( r = LkSetSyntax(syntax, invToken, LK_MAX_TOKENARG_LEN))) 191 | { 192 | printf("\nLkSetSyntax error 0x%08X / element: %ls\n", r, invToken); 193 | free(invToken); 194 | return; 195 | } 196 | 197 | printf("\ncmdline? "); 198 | fgetws (cmdline, 1024, stdin); 199 | cmdline[wcscspn(cmdline, L"\n")] = L'\0'; 200 | 201 | wchar_t invArg[LK_MAX_TOKENARG_LEN]; 202 | if (!LK_SUCCESS(r = LkParse2(cmdline, invArg, LK_MAX_TOKENARG_LEN))) 203 | { 204 | if (r == LK_E_UNKNOWNARG) 205 | { 206 | printf("\nParse error, unknown argument: %ls\n", invArg); 207 | } 208 | free(invToken); 209 | return; 210 | } 211 | 212 | VERIFY(LK_SUCCESS(LkFree())); 213 | } 214 | -------------------------------------------------------------------------------- /vs2015/emulfake.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {AC6BB25F-242D-481B-8CA0-0D3F68375EFE} 23 | Win32Proj 24 | emulfake 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | $(SolutionDir)\obj\$(ProjectName)\$(Platform)\$(Configuration)\ 75 | NativeRecommendedRules.ruleset 76 | 77 | 78 | true 79 | $(SolutionDir)\obj\$(ProjectName)\$(Platform)\$(Configuration)\ 80 | NativeRecommendedRules.ruleset 81 | 82 | 83 | false 84 | $(SolutionDir)\obj\$(ProjectName)\$(Platform)\$(Configuration)\ 85 | NativeRecommendedRules.ruleset 86 | 87 | 88 | false 89 | $(SolutionDir)\obj\$(ProjectName)\$(Platform)\$(Configuration)\ 90 | NativeRecommendedRules.ruleset 91 | 92 | 93 | 94 | 95 | 96 | Level3 97 | Disabled 98 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 99 | 100 | 101 | Console 102 | true 103 | 104 | 105 | 106 | 107 | 108 | 109 | Level3 110 | Disabled 111 | _DEBUG;_WINDOWS;%(PreprocessorDefinitions) 112 | 113 | 114 | Console 115 | true 116 | 117 | 118 | 119 | 120 | Level3 121 | 122 | 123 | MaxSpeed 124 | true 125 | true 126 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 127 | 128 | 129 | Console 130 | true 131 | true 132 | true 133 | 134 | 135 | 136 | 137 | Level3 138 | 139 | 140 | MaxSpeed 141 | true 142 | true 143 | NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 144 | 145 | 146 | Console 147 | true 148 | true 149 | true 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /vs2015/emulfake.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vs2015/linkom_vs.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testrun", "testrun.vcxproj", "{F2ABDD74-FDA1-4078-A912-2B7672E83846}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "emulfake", "emulfake.vcxproj", "{AC6BB25F-242D-481B-8CA0-0D3F68375EFE}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {F2ABDD74-FDA1-4078-A912-2B7672E83846}.Debug|x64.ActiveCfg = Debug|x64 19 | {F2ABDD74-FDA1-4078-A912-2B7672E83846}.Debug|x64.Build.0 = Debug|x64 20 | {F2ABDD74-FDA1-4078-A912-2B7672E83846}.Debug|x86.ActiveCfg = Debug|Win32 21 | {F2ABDD74-FDA1-4078-A912-2B7672E83846}.Debug|x86.Build.0 = Debug|Win32 22 | {F2ABDD74-FDA1-4078-A912-2B7672E83846}.Release|x64.ActiveCfg = Release|x64 23 | {F2ABDD74-FDA1-4078-A912-2B7672E83846}.Release|x64.Build.0 = Release|x64 24 | {F2ABDD74-FDA1-4078-A912-2B7672E83846}.Release|x86.ActiveCfg = Release|Win32 25 | {F2ABDD74-FDA1-4078-A912-2B7672E83846}.Release|x86.Build.0 = Release|Win32 26 | {AC6BB25F-242D-481B-8CA0-0D3F68375EFE}.Debug|x64.ActiveCfg = Debug|x64 27 | {AC6BB25F-242D-481B-8CA0-0D3F68375EFE}.Debug|x64.Build.0 = Debug|x64 28 | {AC6BB25F-242D-481B-8CA0-0D3F68375EFE}.Debug|x86.ActiveCfg = Debug|Win32 29 | {AC6BB25F-242D-481B-8CA0-0D3F68375EFE}.Debug|x86.Build.0 = Debug|Win32 30 | {AC6BB25F-242D-481B-8CA0-0D3F68375EFE}.Release|x64.ActiveCfg = Release|x64 31 | {AC6BB25F-242D-481B-8CA0-0D3F68375EFE}.Release|x64.Build.0 = Release|x64 32 | {AC6BB25F-242D-481B-8CA0-0D3F68375EFE}.Release|x86.ActiveCfg = Release|Win32 33 | {AC6BB25F-242D-481B-8CA0-0D3F68375EFE}.Release|x86.Build.0 = Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /vs2015/testrun.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {F2ABDD74-FDA1-4078-A912-2B7672E83846} 23 | Win32Proj 24 | testrun 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | $(SolutionDir)\obj\$(ProjectName)\$(Platform)\$(Configuration)\ 75 | NativeRecommendedRules.ruleset 76 | 77 | 78 | true 79 | $(SolutionDir)\obj\$(ProjectName)\$(Platform)\$(Configuration)\ 80 | NativeRecommendedRules.ruleset 81 | 82 | 83 | false 84 | $(SolutionDir)\obj\$(ProjectName)\$(Platform)\$(Configuration)\ 85 | NativeRecommendedRules.ruleset 86 | 87 | 88 | false 89 | $(SolutionDir)\obj\$(ProjectName)\$(Platform)\$(Configuration)\ 90 | NativeRecommendedRules.ruleset 91 | 92 | 93 | 94 | 95 | 96 | Level3 97 | Disabled 98 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 99 | 100 | 101 | Console 102 | true 103 | 104 | 105 | 106 | 107 | 108 | 109 | Level3 110 | Disabled 111 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 112 | 113 | 114 | Console 115 | true 116 | 117 | 118 | 119 | 120 | Level3 121 | 122 | 123 | MaxSpeed 124 | true 125 | true 126 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 127 | 128 | 129 | Console 130 | true 131 | true 132 | true 133 | 134 | 135 | 136 | 137 | Level3 138 | 139 | 140 | MaxSpeed 141 | true 142 | true 143 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 144 | 145 | 146 | Console 147 | true 148 | true 149 | true 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /vs2015/testrun.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | --------------------------------------------------------------------------------