├── IaUwpAppx
├── AppManifest.cpp
├── AppManifest.h
├── CAppx.cpp
├── CAppx.h
├── IaUwpAppx.cpp
├── IaUwpAppx.def
├── IaUwpAppx.h
├── IaUwpAppx.rc
├── IaUwpAppx.sln
├── IaUwpAppx.vcxproj
├── IaUwpAppx.vcxproj.filters
├── IaUwpAppxApp.cpp
├── IaUwpAppxApp.h
├── IconExt.cpp
├── IconExt.h
├── PackageFile.cpp
├── PackageFile.h
├── Resource.h
├── VfsPath.cpp
├── VfsPath.h
├── VirtualRegKey.cpp
├── VirtualRegKey.h
├── bin x64
│ ├── IaUwpAppx64.dll
│ ├── IaUwpAppx64.exp
│ └── IaUwpAppx64.lib
├── bin x86
│ ├── IaUwpAppx.dll
│ ├── IaUwpAppx.exp
│ └── IaUwpAppx.lib
├── embedded_res
│ ├── 150x150.png
│ ├── 44x44.png
│ ├── AppxManifest_schema.xml
│ ├── PackageLogo.50x50.png
│ └── main.ico
├── libs
│ ├── DFRegistry.lib
│ ├── DFRegistry64.lib
│ ├── DFRegistry_exp.h
│ ├── dffileop.lib
│ ├── dffileop64.lib
│ ├── dffileop_exp.h
│ └── stdstring.h
├── res
│ └── IaUwpAppx.rc2
├── stdafx.cpp
├── stdafx.h
├── targetver.h
└── utils.h
├── LICENSE
├── README.md
└── Samples
├── Quick Command Line Tool manual.txt
├── bin x64
├── DFRegistry64.dll
├── IaAppxBuilder.exe
├── IaUwpAppx64.dll
└── dffileop64.dll
├── bin x86
├── DFRegistry.dll
├── IaAppxBuilder.exe
├── IaUwpAppx.dll
└── dffileop.dll
├── c#
├── IaAppxBuilder
│ ├── App.config
│ ├── IaAppxBuilder.csproj
│ ├── IaAppxBuilder.csproj.user
│ ├── IaAppxBuilder.sln
│ ├── Program.cs
│ └── Properties
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ ├── Resources.resx
│ │ └── app.manifest
└── LICENSE.txt
└── c++
├── IaAppxBuilder
├── IaAppxBuilder.cpp
├── IaAppxBuilder.sln
├── IaAppxBuilder.vcxproj
├── IaAppxBuilder.vcxproj.filters
├── ReadMe.txt
├── stdafx.cpp
├── stdafx.h
└── targetver.h
└── libs
├── IaUwpAppx.h
├── IaUwpAppx.lib
└── IaUwpAppx64.lib
/IaUwpAppx/AppManifest.cpp:
--------------------------------------------------------------------------------
1 | // FILE: AppManifest.cpp
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #include "stdafx.h"
29 | #include "IaUwpAppxApp.h"
30 | #include "IaUwpAppx.h"
31 | #include "AppManifest.h"
32 |
33 | static const LPCWSTR beginMap[]=
34 | {
35 | _T(" "),
36 | _T("-"),
37 | _T("."),
38 | _T(".."),
39 | _T("con"),
40 | _T("prn"),
41 | _T("aux"),
42 | _T("nul"),
43 | _T("com1"),
44 | _T("com2"),
45 | _T("com3"),
46 | _T("com4"),
47 | _T("com5"),
48 | _T("com6"),
49 | _T("com7"),
50 | _T("com8"),
51 | _T("com9"),
52 | _T("lpt1"),
53 | _T("lpt2"),
54 | _T("lpt3"),
55 | _T("lpt4"),
56 | _T("lpt5"),
57 | _T("lpt6"),
58 | _T("lpt7"),
59 | _T("lpt8"),
60 | _T("lpt9")
61 | };
62 |
63 | static const LPCWSTR equalMap[] =
64 | {
65 | _T("con."),
66 | _T("prn."),
67 | _T("aux."),
68 | _T("nul."),
69 | _T("com1."),
70 | _T("com2."),
71 | _T("com3."),
72 | _T("com4."),
73 | _T("com5."),
74 | _T("com6."),
75 | _T("com7."),
76 | _T("com8."),
77 | _T("com9."),
78 | _T("lpt1."),
79 | _T("lpt2."),
80 | _T("lpt3."),
81 | _T("lpt4."),
82 | _T("lpt5."),
83 | _T("lpt6."),
84 | _T("lpt7."),
85 | _T("lpt8."),
86 | _T("lpt9."),
87 | _T("xn--")
88 | };
89 |
90 |
91 | CAppManifest::CAppManifest()
92 | {
93 | m_vElem.resize(MAX_ELEMENTS);
94 | }
95 |
96 | CAppManifest::~CAppManifest()
97 | {
98 | }
99 |
100 | UINT CAppManifest::CheckElement(LPCWSTR lpwValue, Attribute attribute, CStdStringW& checkedOut)
101 | {
102 | UINT result = UAPPX_SUCCESS;
103 |
104 | checkedOut.clear();
105 |
106 | if (!lpwValue)
107 | return UAPPX_PARAM_ERROR;
108 |
109 | CStdStringW sBuffer(lpwValue);
110 |
111 | if (sBuffer.IsEmpty())
112 | return UAPPX_INVALID_MANIFEST_VALUE;
113 |
114 | if (attribute == IdentityName)
115 | {
116 | size_t len = sBuffer.length();
117 |
118 | // Required a string between 3 and 50 characters in length
119 | if (3 > len || 50 < len)
120 | {
121 | return UAPPX_INVALID_MANIFEST_VALUE;
122 | }
123 |
124 | // Remove firsts non alphanumeric char from string
125 | for (size_t i = 0; i < sBuffer.length(); i++)
126 | {
127 | wchar_t c = sBuffer.at(i);
128 | if (!(iswalpha(c) || iswdigit(c)) || (c == 0x20))
129 | {
130 | sBuffer.Delete(0, 1);
131 | }
132 | else
133 | {
134 | break;
135 | }
136 | }
137 |
138 | size_t size = sizeof(beginMap) / sizeof(beginMap[0]);
139 |
140 | for (size_t i = 0; i < size; i++)
141 | {
142 | CStdStringW s(beginMap[i]);
143 |
144 | if (g_StringBegins_with(sBuffer, s))
145 | {
146 | sBuffer.Delete(0, (int)s.length());
147 | }
148 | }
149 |
150 | size = sizeof(equalMap) / sizeof(equalMap[0]);
151 |
152 | for (size_t i = 0; i < size; i++)
153 | {
154 | if (sBuffer.CompareNoCase(equalMap[i]) == 0)
155 | {
156 | result = UAPPX_INVALID_MANIFEST_VALUE;
157 | break;
158 | }
159 | }
160 |
161 | for (CStdStringW::iterator it = sBuffer.begin(); it < sBuffer.end(); ++it)
162 | {
163 | // This replaces forbidden characters with Hyphen.
164 | switch (*it)
165 | {
166 | case 0x20:
167 | case 0x22:
168 | case 0x2f:
169 | case 0x3a:
170 | case 0x3b:
171 | case 0x3c:
172 | case 0x3e:
173 | case 0x3f:
174 | case 0x5c:
175 | (*it) = 0x2d;
176 | break;
177 |
178 | default:
179 | (*it) = *it;
180 | break;
181 | }
182 | }
183 |
184 | len = sBuffer.length();
185 |
186 | if (len > 1)
187 | {
188 | if (sBuffer.at(len - 1) == 0x2e) //('.')
189 | {
190 | sBuffer.Delete((int)len - 1);
191 | }
192 | }
193 |
194 | len = sBuffer.length();
195 |
196 | // Required a string between 3 and 50 characters in length
197 | if (3 > len || 50 < len)
198 | {
199 | return UAPPX_INVALID_MANIFEST_VALUE;
200 | }
201 | }
202 | else if (attribute == DisplayName)
203 | {
204 | size_t len = sBuffer.length();
205 |
206 | // Required a string between 1 and 256 characters in length
207 | if (1 > len || 256 < len)
208 | {
209 | return UAPPX_INVALID_MANIFEST_VALUE;
210 | }
211 |
212 | // Remove firsts non alphanumeric char from string
213 | for (size_t i = 0; i < sBuffer.length(); i++)
214 | {
215 | wchar_t c = sBuffer.at(i);
216 | if (!(iswalpha(c) || iswdigit(c)) || (c == 0x20))
217 | {
218 | sBuffer.Delete(0, 1);
219 | }
220 | else
221 | {
222 | break;
223 | }
224 | }
225 |
226 | len = sBuffer.length();
227 |
228 | // Required a string between 1 and 256 characters in length
229 | if (1 > len || 256 < len)
230 | {
231 | return UAPPX_INVALID_MANIFEST_VALUE;
232 | }
233 | }
234 | else if (attribute == Version)
235 | {
236 | vector result;
237 | g_StdStrSplit(sBuffer, 0x2e, result);
238 |
239 | size_t size = result.size();
240 |
241 | if (size != 4)
242 | {
243 | //Version string has to be in quad notation, "Major.Minor.Build.Revision".
244 |
245 | sBuffer.clear();
246 |
247 | while (size > 4)
248 | {
249 | g_VectorRemoveElement(result, size - 1);
250 | size = result.size();
251 | }
252 |
253 | while (size < 4)
254 | {
255 | result.push_back(_T("0"));
256 | size = result.size();
257 | }
258 |
259 | for (size_t i = 0; (i < 4) && (i < size); i++)
260 | {
261 | sBuffer += result[i];
262 |
263 | if ((i + 1 < 4) && (i + 1 < size))
264 | sBuffer += _T(".");
265 | }
266 | }
267 | }
268 | else if (attribute == PublisherDisplayName)
269 | {
270 | sBuffer.Format(_T("CN=%s"), lpwValue);
271 | }
272 |
273 | if (result == UAPPX_SUCCESS)
274 | checkedOut = sBuffer;
275 |
276 | return result;
277 | }
278 |
279 | UINT CAppManifest::SetElement(LPCWSTR lpwValue, Attribute attribute)
280 | {
281 | UINT result = UAPPX_SUCCESS;
282 |
283 | CStdStringW sBuffer(_T(""));
284 | result = CheckElement(lpwValue, attribute, sBuffer);
285 |
286 | if(result == UAPPX_SUCCESS)
287 | m_vElem[(size_t)attribute] = sBuffer;
288 |
289 | return result;
290 | }
291 |
292 | UINT CAppManifest::SetApplicationNode(CShortcut& shortcut, LPCWSTR lpwExecutable, LPCWSTR lpw150x150Logo, LPCWSTR lpw44x44Logo, CAssociation& association)
293 | {
294 | UINT result = UAPPX_SUCCESS;
295 |
296 | if (shortcut.m_sName.IsEmpty() || !lpwExecutable || !lpw150x150Logo || !lpw44x44Logo)
297 | return UAPPX_PARAM_ERROR;
298 |
299 | do
300 | {
301 | CStdStringW sFmt(_T("\n") \
302 | _T("\t\n"));
303 |
304 | // Application ID
305 | CStdStringW sApplicationId(_T(""));
306 |
307 | size_t nSize = 0;
308 | if (DF_GetFileName(lpwExecutable, NULL, &nSize))
309 | {
310 | nSize += 1;
311 | LPWSTR p = sApplicationId.GetBuffer((int)nSize);
312 | DF_GetFileName(lpwExecutable, p, &nSize);
313 | DF_RemoveExt(p, nSize);
314 | sApplicationId.ReleaseBuffer();
315 | }
316 |
317 | if (shortcut.m_bEntryPoint)
318 | {
319 | sApplicationId.Format(_T("A%s"), sApplicationId);
320 | }
321 |
322 | CStdStringW sApplicationNode(_T(""));
323 | sApplicationNode.Format(sFmt.c_str(), sApplicationId, lpwExecutable, shortcut.m_sName, shortcut.m_sDescription, lpw150x150Logo, lpw44x44Logo);
324 |
325 | size_t size = m_vElem.size();
326 | m_vElem.resize(size + 1);
327 |
328 | if (size > MAX_ELEMENTS)
329 | {
330 | sApplicationNode.Format(_T("\n%s"), sApplicationNode);
331 | }
332 |
333 | if (association.m_vExt.size() > 0)
334 | {
335 | /*sFmt = _T("\n\n\n");
336 | sFmt.Format(sFmt, association.m_sId);
337 | sFmt.append(_T("\n%s\n"));*/
338 |
339 | sFmt = _T("\n\n\n") \
340 | _T("\n%s\n");
341 |
342 | CStdStringW sFileTypeNodes(_T(""));
343 |
344 | std::vector::const_iterator iter;
345 | for (iter = association.m_vExt.begin(); iter != association.m_vExt.end(); iter++)
346 | {
347 | CStdStringW sExt = (CStdStringW)*iter;
348 |
349 | CStdStringW sNode(_T(""));
350 | sNode.Format(_T("%s\n"), sExt);
351 | sFileTypeNodes.append(sNode);
352 | }
353 |
354 | CStdStringW sExtensionsNode(_T(""));
355 | sExtensionsNode.Format(sFmt, sFileTypeNodes);
356 |
357 | if (!association.m_sIconVFSpath.IsEmpty())
358 | {
359 | CStdStringW sNode(_T(""));
360 | sNode.Format(_T("%s\n"), association.m_sIconVFSpath);
361 | sExtensionsNode.append(sNode);
362 | }
363 |
364 | // Close FileTypeAssociation node
365 | sExtensionsNode.append(_T("\n\n\n"));
366 |
367 | sApplicationNode.append(sExtensionsNode);
368 | }
369 |
370 | // Close Application node
371 | sApplicationNode.append(_T(""));
372 |
373 | m_vElem[size] = sApplicationNode.c_str();
374 |
375 | } while (FALSE);
376 |
377 | return result;
378 | }
379 |
380 | UINT CAppManifest::Do(CStdStringW sCertificate, CStdStringW sCertPassword)
381 | {
382 | UINT result = UAPPX_SUCCESS;
383 |
384 | do
385 | {
386 | // Process publisher certificate, if any.
387 | if (sCertificate.IsEmpty())
388 | {
389 | m_vElem[(size_t)Publisher] = m_vElem[(size_t)PublisherDisplayName];
390 | }
391 | else
392 | {
393 | // Get publisher "subject" from certificate file.
394 | LPWSTR pwSubject = NULL;
395 |
396 | DWORD dwRet = g_GetCertificateSubject(sCertificate.c_str(), sCertPassword.c_str(), pwSubject);
397 |
398 | if (dwRet != ERROR_SUCCESS)
399 | {
400 | switch (dwRet)
401 | {
402 | case ERROR_FILE_NOT_FOUND:
403 | case ERROR_PATH_NOT_FOUND:
404 | result = UAPPX_CERTIFICATE_FILE_NOT_FOUND;
405 | break;
406 |
407 | case ERROR_INVALID_HANDLE:
408 | case ERROR_ACCESS_DENIED:
409 | result = UAPPX_CERTIFICATE_FILE_ACCESS_ERROR;
410 | break;
411 |
412 | case ERROR_INVALID_PASSWORD:
413 | result = UAPPX_CERTIFICATE_INVALID_PASSWORD;
414 | break;
415 |
416 | default:
417 | result = UAPPX_CERTIFICATE_ERROR;
418 | break;
419 | }
420 |
421 | break;
422 | }
423 |
424 | CStdStringW sSubject(pwSubject);
425 | delete[] pwSubject;
426 |
427 | CStdString sResult(_T(""));
428 | FormatCertificateSubject(sSubject, sResult);
429 |
430 | if(sResult.IsEmpty())
431 | {
432 | result = UAPPX_CERTIFICATE_ERROR;
433 | break;
434 | }
435 |
436 | m_vElem[(size_t)Publisher] = sResult;
437 | }
438 |
439 | CStdStringW sSchema(m_sPath + _T("\\schema.xml"));
440 | CStdStringW sAppManifest(m_sPath + _T("\\AppxManifest.xml"));
441 |
442 | if (!g_ExtractModuleResource(IDR_XMLAPPMANIFEST1, _T("XMLAPPMANIFEST"), sSchema.c_str()))
443 | {
444 | result = UAPPX_UNEXPECTED_MODULE_RESOURCE_ERROR;
445 | break;
446 | }
447 |
448 | wfstream in(sSchema);
449 | wofstream out(sAppManifest);
450 |
451 | if (!in || !out)
452 | {
453 | result = UAPPX_CREATE_MANIFEST_ERROR;
454 | break;
455 | }
456 |
457 | UpdateManifest(in, out);
458 |
459 | in.close();
460 | DF_DeleteFile(sSchema.c_str());
461 |
462 | } while (FALSE);
463 |
464 | return result;
465 | }
466 |
467 | void CAppManifest::UpdateManifest(wistream& in, wostream& out)
468 | {
469 | UINT uTokens = 0;
470 | size_t eSize = m_vElem.size();
471 | size_t iDx = 0;
472 |
473 | wchar_t c;
474 | while (in.get(c))
475 | {
476 | if (c != _T('$'))
477 | {
478 | uTokens = 0;
479 | out.put(c);
480 | }
481 | else
482 | {
483 | if (++uTokens == 3)
484 | {
485 | if (iDx < eSize)
486 | {
487 | if(iDx < MAX_ELEMENTS)
488 | {
489 | out << m_vElem[iDx++].c_str();
490 | }
491 | else
492 | {
493 | size_t nAppNode = eSize - MAX_ELEMENTS;
494 |
495 | for (; iDx < eSize; iDx++)
496 | {
497 | out << m_vElem[iDx].c_str();
498 | }
499 | }
500 | }
501 |
502 | uTokens = 0;
503 | }
504 | }
505 | }
506 | }
507 |
508 | void CAppManifest::FormatCertificateSubject(CStdString str, CStdString& result)
509 | {
510 | std::vector v;
511 |
512 | size_t cutAt;
513 | while ((cutAt = str.find_first_of(0x2c)) != str.npos)
514 | {
515 | if (cutAt > 0)
516 | {
517 | CStdString sSubstring(str.substr(0, cutAt));
518 |
519 | if(sSubstring.at(0) != 0x20)// If not space, add one at zero index.
520 | sSubstring.Format(_T(" %s"), sSubstring);
521 |
522 | if (sSubstring.find_first_of(0x3d) == CStdString::npos)
523 | {
524 | sSubstring.Format(_T(",%s"), sSubstring);
525 | }
526 |
527 | v.push_back(sSubstring);
528 | }
529 | str = str.substr(cutAt + 1);
530 | }
531 |
532 | if (str.length() > 0)
533 | {
534 | v.push_back(str);
535 | }
536 |
537 | size_t vSize = v.size();
538 |
539 | if (vSize > 0)
540 | {
541 | CStdString sTempBuff(_T(""));
542 | for (int i = (int)(vSize-1); i >= 0; i--)
543 | {
544 | CStdStringW sSubstring(_T(""));
545 | sSubstring = v[(size_t)i];
546 |
547 | if (sSubstring.find_first_of(0x2c) != CStdString::npos)
548 | {
549 | sTempBuff.append(sSubstring);
550 | }
551 | else
552 | {
553 | if (!sTempBuff.IsEmpty())
554 | {
555 | sSubstring.append(sTempBuff);
556 | sTempBuff.clear();
557 | }
558 |
559 | if(!result.IsEmpty())
560 | sSubstring.Format(_T(",%s"), sSubstring);
561 | else
562 | {
563 | if (sSubstring.at(0) == 0x20)
564 | sSubstring.Delete(0);
565 | }
566 |
567 | sSubstring.Replace(_T("\""), _T("""));
568 | result.append(sSubstring);
569 | }
570 | }
571 | }
572 | }
--------------------------------------------------------------------------------
/IaUwpAppx/AppManifest.h:
--------------------------------------------------------------------------------
1 | // FILE: AppManifest.h
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #pragma once
29 |
30 | #define MAX_ELEMENTS 8
31 |
32 | class CAppManifest
33 | {
34 | public:
35 | CAppManifest();
36 | ~CAppManifest();
37 |
38 | enum Attribute
39 | {
40 | IdentityName,
41 | ProcessorArchitecture,
42 | Publisher,
43 | Version,
44 | DisplayName,
45 | PublisherDisplayName,
46 | Logo,
47 | ResourceLanguage
48 | };
49 |
50 | static UINT CheckElement(LPCWSTR lpwValue, Attribute attribute, CStdStringW& checkedOut);
51 |
52 | UINT SetElement(LPCWSTR lpwValue, Attribute attribute);
53 |
54 | UINT SetApplicationNode(CShortcut& shortcut, LPCWSTR lpwExecutable, LPCWSTR lpw150x150Logo, LPCWSTR lpw44x44Logo, CAssociation& association);
55 |
56 | void SetPath(CStdStringW sPath)
57 | {
58 | m_sPath = sPath;
59 | }
60 |
61 | UINT Do(CStdStringW sCertificate, CStdStringW sCertPassword);
62 |
63 |
64 | protected:
65 | CStdStringW m_sPath;
66 | vector m_vElem;
67 | vector m_vApplicationNodes;
68 |
69 | protected:
70 | void UpdateManifest(wistream& in, wostream& out);
71 | void FormatCertificateSubject(CStdString str, CStdString& result);
72 | };
73 |
74 |
--------------------------------------------------------------------------------
/IaUwpAppx/CAppx.cpp:
--------------------------------------------------------------------------------
1 | // FILE: CAppx.cpp
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #include "stdafx.h"
29 | #include "IaUwpAppxApp.h"
30 | #include "IaUwpAppx.h"
31 | #include "CAppx.h"
32 |
33 | #include "IconExt.h"
34 |
35 | void CALLBACK DF_VFS_enum(LPARAM param, LPARAM data)
36 | {
37 | vector* pThis = (vector*)param;
38 | DF_FILEOP_VFS_DATA* pData = (DF_FILEOP_VFS_DATA*)data;
39 |
40 | if (!pThis || !pData)
41 | return;
42 |
43 | if (pData->pwName && pData->pwSysPath)
44 | {
45 | CVfsPath vfs;
46 | vfs.Set(pData->pwName, pData->pwSysPath);
47 | pThis->push_back(vfs);
48 | }
49 | }
50 |
51 | CAppx::CAppx(LPCWSTR lpPackagename, LPCWSTR lpPackagepath, bool b64BitPackage)
52 | {
53 | m_packageName = lpPackagename;
54 | m_PackagePath = lpPackagepath;
55 | m_b64BitPackage = b64BitPackage;
56 |
57 | m_winSdkPath = _T("C:\\Program Files (x86)\\Windows Kits\\10\\bin\\x86");
58 |
59 | m_TempPath = _T("");
60 |
61 | m_sAuthenticodeCert = _T("");
62 | m_sAuthenticodeCertPwd = _T("");
63 | m_sAuthenticodeTimestamp = _T("");
64 |
65 | m_packageHasShortcut = false;
66 | }
67 |
68 | CAppx::~CAppx(void)
69 | {
70 | std::vector::const_iterator iter;
71 | for (iter = m_vRegkeyList.begin(); iter != m_vRegkeyList.end(); iter++)
72 | {
73 | CVirtualRegKey key = (CVirtualRegKey)*iter;
74 | key.Clear();
75 | }
76 | }
77 |
78 | UINT CAppx::Initialize()
79 | {
80 | UINT result = UAPPX_SUCCESS;
81 |
82 | if (DF_EnumerateKnownFoldersW(DF_VFS_enum, (LPARAM)&m_vVfsPaths) != DFFILEOP_SUCCESS)
83 | {
84 | result = UAPPX_SYS_PATHS_ENUM_ERROR;
85 | }
86 |
87 | return result;
88 | }
89 |
90 | void CAppx::AddVRegKey(CVirtualRegKey& vKey)
91 | {
92 | if (!(std::find(m_vRegkeyList.begin(), m_vRegkeyList.end(), vKey) != m_vRegkeyList.end()))
93 | {
94 | /* v does not contain x */
95 | m_vRegkeyList.push_back(vKey);
96 | }
97 | }
98 |
99 | UINT CAppx::AddFile(LPCWSTR lpwSource, LPCWSTR lpwTarget, size_t* pFileIdx)
100 | {
101 | UINT result = UAPPX_SUCCESS;
102 |
103 | do
104 | {
105 | CPackageFile file;
106 |
107 | result = file.Set(lpwSource, lpwTarget, m_vVfsPaths);
108 | if (result != UAPPX_SUCCESS)
109 | {
110 | break;
111 | }
112 |
113 | if (!(std::find(m_vFileList.begin(), m_vFileList.end(), file) != m_vFileList.end()))
114 | {
115 | /* v does not contain file */
116 | m_vFileList.push_back(file);
117 | *pFileIdx = m_vFileList.size();
118 | }
119 |
120 | } while (FALSE);
121 |
122 | return result;
123 | }
124 |
125 | UINT CAppx::AddDirectory(LPCWSTR lpwTarget, size_t* pFileIdx)
126 | {
127 | UINT result = UAPPX_SUCCESS;
128 |
129 | do
130 | {
131 | CPackageFile file;
132 |
133 | result = file.Set(lpwTarget, m_vVfsPaths);
134 | if (result != UAPPX_SUCCESS)
135 | {
136 | break;
137 | }
138 |
139 | if (!(std::find(m_vFileList.begin(), m_vFileList.end(), file) != m_vFileList.end()))
140 | {
141 | /* v does not contain file */
142 | m_vFileList.push_back(file);
143 | *pFileIdx = m_vFileList.size();
144 | }
145 |
146 | } while (FALSE);
147 |
148 | return result;
149 | }
150 |
151 | UINT CAppx::AddShortcut(size_t fileIdx, LPCWSTR lpwName, LPCWSTR lpwDescription, LPCWSTR lpwPath, LPCWSTR lpwCommandline, PCWSTR lpwIconfile, int iconIdx)
152 | {
153 | UINT result = UAPPX_SUCCESS;
154 |
155 | // NOTE
156 | // lpwPath, pwCommandline and lpwIconfile can be null
157 | if (fileIdx == 0 || !lpwName/* || !lpwPath*/)
158 | {
159 | result = UAPPX_PARAM_ERROR;
160 | }
161 |
162 | do
163 | {
164 | if (fileIdx > m_vFileList.size())
165 | {
166 | result = UAPPX_PARAM_ERROR;
167 | break;
168 | }
169 |
170 | CPackageFile* file = &m_vFileList[fileIdx-1];
171 |
172 | if(!file)
173 | {
174 | result = UAPPX_PARAM_ERROR;
175 | break;
176 | }
177 |
178 | CShortcut shortCut;
179 |
180 | if (!m_packageHasShortcut)
181 | {
182 | shortCut.m_bEntryPoint = true;
183 | }
184 |
185 | shortCut.m_sName = lpwName;
186 | if (lpwDescription)
187 | shortCut.m_sDescription = lpwDescription;
188 | if(lpwPath)
189 | shortCut.m_sPath = lpwPath;
190 | if (lpwCommandline)
191 | shortCut.m_sCmdline = lpwCommandline;
192 | shortCut.m_sIconfile = lpwIconfile;
193 | shortCut.m_iconIdx = iconIdx;
194 |
195 | file->Set(shortCut);
196 |
197 | m_packageHasShortcut = true;
198 |
199 | } while (FALSE);
200 |
201 | return result;
202 | }
203 |
204 | UINT CAppx::SetFileAssociation(size_t fileIdx, LPCWSTR lpwProgId, LPCWSTR lpwDescription, LPCWSTR** lpwExtensions, size_t extSize, LPCWSTR lpwIconfile, int iconIdx)
205 | {
206 | UINT result = UAPPX_SUCCESS;
207 |
208 | // NOTE
209 | // lpwIconfile - Icon path can be null
210 |
211 | do
212 | {
213 | if (fileIdx > m_vFileList.size())
214 | {
215 | result = UAPPX_PARAM_ERROR;
216 | break;
217 | }
218 |
219 | CPackageFile* file = &m_vFileList[fileIdx - 1];
220 |
221 | if (!file)
222 | {
223 | result = UAPPX_PARAM_ERROR;
224 | break;
225 | }
226 |
227 | CAssociation association;
228 |
229 | if (lpwProgId)
230 | association.m_sId = lpwProgId;
231 |
232 | if (lpwDescription)
233 | association.m_sDescription = lpwDescription;
234 |
235 | if (lpwIconfile)
236 | {
237 | association.m_sIconfile = lpwIconfile;
238 | association.m_iconIdx = iconIdx;
239 | }
240 |
241 | if (extSize > 0 && *lpwExtensions)
242 | {
243 | for (size_t i = 0; i < extSize; i++)
244 | {
245 | LPCWSTR pw = (*lpwExtensions)[i];
246 | association.m_vExt.push_back(pw);
247 | }
248 | }
249 |
250 | file->Set(association);
251 |
252 | } while (FALSE);
253 |
254 | return result;
255 | }
256 |
257 | UINT CAppx::ProcessPackage(void)
258 | {
259 | UINT result = UAPPX_SUCCESS;
260 |
261 | do
262 | {
263 | if (!m_packageHasShortcut)
264 | {
265 | result = UAPPX_NO_SHORTCUT_DEFINED;
266 | break;
267 | }
268 |
269 | // Create temporary package location
270 | m_TempPath = g_GetTempDirectory();
271 |
272 | if (m_TempPath.IsEmpty())
273 | {
274 | result = UAPPX_FAILURE;
275 | break;
276 | }
277 |
278 | m_TempPath.Format(_T("%s%s"), m_TempPath, g_GetGuId());
279 |
280 | if (DF_DirExist(m_TempPath.c_str()))
281 | {
282 | m_TempPath = g_GetTempDirectory();
283 | m_TempPath.Format(_T("%s%s"), m_TempPath, g_GetGuId());
284 | }
285 |
286 | if (!DF_CreateDirectory(m_TempPath.c_str(), NULL))
287 | {
288 | result = UAPPX_FILE_ACCESS_ERROR;
289 | break;
290 | }
291 |
292 | // Initialize AppManifest values
293 | m_appManifest.SetPath(m_TempPath);
294 |
295 | if(m_b64BitPackage)
296 | m_appManifest.SetElement(_T("x64"), CAppManifest::ProcessorArchitecture);
297 | else
298 | m_appManifest.SetElement(_T("x86"), CAppManifest::ProcessorArchitecture);
299 |
300 | // registry dat
301 | result = FinalizeRegistry();
302 | if (result != UAPPX_SUCCESS)
303 | {
304 | break;
305 | }
306 |
307 | // Virtual File System
308 | result = FinalizeVirtualFileSystem();
309 | if (result != UAPPX_SUCCESS)
310 | {
311 | break;
312 | }
313 |
314 | // Package ASSETS items
315 | result = FinalizeAssets();
316 | if (result != UAPPX_SUCCESS)
317 | {
318 | break;
319 | }
320 |
321 | // Package manifest
322 | result = FinalizeAppManifest();
323 | if (result != UAPPX_SUCCESS)
324 | {
325 | break;
326 | }
327 |
328 | // Generate APPX container
329 | result = FinalizeAppXcontainer();
330 |
331 | } while (FALSE);
332 |
333 | DF_DeleteDirectory(m_TempPath.c_str(), TRUE, NULL, NULL);
334 |
335 | return result;
336 | }
337 |
338 | UINT CAppx::SetDisplayName(LPCWSTR lpwValue)
339 | {
340 | UINT result = m_appManifest.SetElement(lpwValue, CAppManifest::IdentityName);
341 |
342 | if(result == UAPPX_SUCCESS)
343 | result = m_appManifest.SetElement(lpwValue, CAppManifest::DisplayName);
344 |
345 | return result;
346 | }
347 |
348 | UINT CAppx::SetLanguage(LPCWSTR lpwValue)
349 | {
350 | return m_appManifest.SetElement(lpwValue, CAppManifest::ResourceLanguage);
351 |
352 | return UAPPX_SUCCESS;
353 | }
354 |
355 | UINT CAppx::SetPublisherCertificate(LPCWSTR lpwCertificate, LPCWSTR lpwPassword, LPCWSTR lpwTimestamp)
356 | {
357 | if (!lpwCertificate || !lpwPassword)
358 | return UAPPX_PARAM_ERROR;
359 |
360 | m_sAuthenticodeCert = lpwCertificate;
361 | m_sAuthenticodeCertPwd = lpwPassword;
362 |
363 | if(lpwTimestamp)
364 | m_sAuthenticodeTimestamp = lpwTimestamp;
365 |
366 | return UAPPX_SUCCESS;
367 | }
368 |
369 | UINT CAppx::SetPublisher(LPCWSTR lpwValue)
370 | {
371 | return m_appManifest.SetElement(lpwValue, CAppManifest::PublisherDisplayName);
372 | }
373 |
374 | UINT CAppx::SetVersion(LPCWSTR lpwValue)
375 | {
376 | return m_appManifest.SetElement(lpwValue, CAppManifest::Version);
377 | }
378 |
379 | bool CAppx::SetWinSdkBinPath(LPCWSTR lpwBinPath)
380 | {
381 | bool result = false;
382 |
383 | if (lpwBinPath)
384 | {
385 | if (DF_DirExist(lpwBinPath))
386 | {
387 | m_winSdkPath = lpwBinPath;
388 | result = true;
389 | }
390 | }
391 |
392 | return result;
393 | }
394 |
395 | UINT CAppx::FinalizeRegistry(void)
396 | {
397 | UINT result = UAPPX_SUCCESS;
398 | bool bRet = true;
399 |
400 | CStdStringW sGuId = _T("");
401 | sGuId.Format(_T("{%s}"), g_GetGuId());
402 |
403 | if (!g_SetRegKeyPermission(sGuId.c_str()))
404 | {
405 | return UAPPX_REG_DAT_SECURITY_DESCRIPTOR_ERROR;
406 | }
407 |
408 | do
409 | {
410 | std::vector::const_iterator iter;
411 | for (iter = m_vRegkeyList.begin(); iter != m_vRegkeyList.end(); iter++)
412 | {
413 | CVirtualRegKey key = (CVirtualRegKey)*iter;
414 |
415 | if (!key.IsUnSupported())
416 | {
417 | CStdStringW sSubKey = _T("");
418 | sSubKey.Format(_T("%s\\%s"), sGuId, key.GetSubKey());
419 |
420 | CStdStringW sValName = _T("");
421 | sValName = key.GetValueName();
422 |
423 | DWORD dwType = 0;
424 | LPVOID pValue = key.GetValue(dwType);
425 |
426 | switch (dwType)
427 | {
428 | case REG_BINARY:
429 | {
430 | DWORD size = key.GetBinaryValueSize();
431 | bRet = DFREG_SaveBinary(HKEY_CURRENT_USER, sSubKey.c_str(), sValName, (LPBYTE)pValue, size);
432 | }
433 | break;
434 |
435 | case REG_DWORD:
436 | {
437 | DWORD dwValue = *(LPDWORD)pValue;
438 | bRet = DFREG_SaveNumber(HKEY_CURRENT_USER, sSubKey.c_str(), sValName, dwValue);
439 | }
440 | break;
441 |
442 | //case REG_QWORD:
443 | // // Not handled!
444 | // result = false;
445 | // break;
446 |
447 | case REG_SZ:
448 | case REG_EXPAND_SZ:
449 | case REG_LINK:
450 | {
451 | CStdStringW sValue = ((CStdStringW*)pValue)->c_str();
452 |
453 | if(dwType == REG_EXPAND_SZ)
454 | bRet = DFREG_SaveExpandedString(HKEY_CURRENT_USER, sSubKey.c_str(), sValName, sValue.c_str());
455 | else
456 | bRet = DFREG_SaveString(HKEY_CURRENT_USER, sSubKey.c_str(), sValName, sValue.c_str());
457 | }
458 | break;
459 |
460 | case REG_MULTI_SZ:
461 | {
462 | CStdStringW sValue = ((CStdStringW*)pValue)->c_str();
463 |
464 | int len = (int)sValue.length() + 2;
465 | LPWSTR p = sValue.GetBuffer(len);
466 | p[len - 1] = _T('\0');
467 | bRet = DFREG_SaveMultiString(HKEY_CURRENT_USER, sSubKey.c_str(), sValName, p);
468 | sValue.ReleaseBuffer();
469 | }
470 | break;
471 |
472 | default:
473 | //result = false;
474 | break;
475 | }
476 | }
477 |
478 | if (!bRet)
479 | {
480 | result = UAPPX_REG_DAT_ERROR;
481 | break;
482 | }
483 | }
484 |
485 | if (result != UAPPX_SUCCESS)
486 | {
487 | break;
488 | }
489 |
490 | // Export
491 | HKEY hKey = DFREG_Open(HKEY_CURRENT_USER, sGuId.c_str(), KEY_ALL_ACCESS);
492 |
493 | if (hKey)
494 | {
495 | CStdStringW sTargetFile(_T(""));
496 | sTargetFile.Format(_T("%s\\Registry.dat"), m_TempPath);
497 |
498 | if (DFREG_ExportKey(hKey, sTargetFile.c_str(), NULL) != ERROR_SUCCESS)
499 | {
500 | DF_DeleteFile(sTargetFile.c_str());
501 | result = UAPPX_REG_DAT_PRIVILEGE_ERROR;
502 | }
503 |
504 | DFREG_Close(hKey);
505 | }
506 | else
507 | {
508 | result = UAPPX_REG_DAT_ERROR;
509 | break;
510 | }
511 |
512 | } while (FALSE);
513 |
514 | // Do cleanup
515 | bRet = DFREG_DeletelKey(HKEY_CURRENT_USER, sGuId.c_str(), NULL);
516 |
517 | return result;
518 | }
519 |
520 | UINT CAppx::FinalizeVirtualFileSystem(void)
521 | {
522 | UINT result = UAPPX_SUCCESS;
523 |
524 | do
525 | {
526 | // Copy source files to VFS temp directory
527 | std::vector::const_iterator fileIter;
528 | for (fileIter = m_vFileList.begin(); fileIter != m_vFileList.end(); fileIter++)
529 | {
530 | bool isVFS_File = true;
531 |
532 | CPackageFile file = (CPackageFile)*fileIter;
533 |
534 | if (lstrlen(file.GetSourcePath()) == 0)
535 | {
536 | isVFS_File = false;
537 | }
538 |
539 | CStdStringW sTargetFile(_T(""));
540 | sTargetFile.Format(_T("%s\\%s"), m_TempPath, file.GetVFSpath());
541 |
542 | CStdStringW sTargetDir(sTargetFile);
543 |
544 | if (isVFS_File)
545 | {
546 | size_t nSize = sTargetDir.GetLength() + 1;
547 | LPWSTR p = sTargetDir.GetBuffer((int)nSize);
548 | DF_RemoveFileName(p, nSize);
549 | sTargetDir.ReleaseBuffer();
550 | }
551 |
552 | if (!DF_DirExist(sTargetDir.c_str()))
553 | {
554 | if (!DF_CreateDirectory(sTargetDir.c_str(), NULL))
555 | {
556 | result = UAPPX_FILE_ACCESS_ERROR;
557 | break;
558 | }
559 | }
560 |
561 | if (!isVFS_File)
562 | {
563 | // Skip this, it's a directory not a file!
564 | continue;
565 | }
566 |
567 | if(!DF_CopyFile(file.GetSourcePath(), sTargetFile.c_str(), false))
568 | {
569 | result = UAPPX_VFSFILE_COPY_ERROR;
570 | break;
571 | }
572 | }
573 |
574 | if (result != UAPPX_SUCCESS)
575 | {
576 | break;
577 | }
578 |
579 | } while (FALSE);
580 |
581 | return result;
582 | }
583 |
584 | UINT CAppx::FinalizeAssets()
585 | {
586 | UINT result = UAPPX_SUCCESS;
587 |
588 | do
589 | {
590 | // Create ASSETS directory
591 | CStdStringW sTargetDir(_T(""));
592 | sTargetDir.Format(_T("%s\\%s"), m_TempPath, _T("ASSETS"));
593 | if (!DF_CreateDirectory(sTargetDir.c_str(), NULL))
594 | {
595 | result = UAPPX_FILE_ACCESS_ERROR;
596 | break;
597 | }
598 |
599 | if (!g_ExtractModuleResource(IDR_ASSETS_50, _T("ASSETS"), CStdStringW(sTargetDir + _T("\\PackageLogo.50x50.png")).c_str()))
600 | {
601 | result = UAPPX_UNEXPECTED_MODULE_RESOURCE_ERROR;
602 | break;
603 | }
604 |
605 | result = m_appManifest.SetElement((CStdStringW(_T("Assets")) + _T("\\PackageLogo.50x50.png")).c_str(), CAppManifest::Logo);
606 | if (result != UAPPX_SUCCESS)
607 | {
608 | result = UAPPX_UNEXPECTED_MODULE_RESOURCE_ERROR;
609 | break;
610 | }
611 |
612 | vector::const_iterator fileIter;
613 | for (fileIter = m_vFileList.begin(); fileIter != m_vFileList.end(); fileIter++)
614 | {
615 | CPackageFile file = (CPackageFile)*fileIter;
616 |
617 | CShortcut shortCut = file.GetShortcut();
618 |
619 | if (shortCut.m_sName.IsEmpty())
620 | continue;
621 |
622 | int iDx = -1;
623 | CStdStringW sImageFile(_T(""));
624 | if (!shortCut.m_sIconfile.IsEmpty())
625 | {
626 | sImageFile = shortCut.m_sIconfile;
627 | iDx = shortCut.m_iconIdx;
628 | }
629 | else
630 | {
631 | sImageFile = file.GetSourcePath();
632 | }
633 |
634 | // Application 150x150 asset image
635 | CStdStringW s150x150img_VFSpath(_T(""));
636 | s150x150img_VFSpath.Format(_T("Assets\\%s.150x150.png"), shortCut.m_sName);
637 |
638 | bool bIconDone = false;
639 | CIconExt icon;
640 | if (icon.Load(sImageFile.c_str(), iDx, 150, 150))
641 | {
642 | bIconDone = icon.SaveAsPng(CStdStringW(m_TempPath + _T("\\") + s150x150img_VFSpath.c_str()).c_str());
643 | }
644 |
645 | if (!bIconDone)
646 | {
647 | if (!g_ExtractModuleResource(IDR_ASSETS_150, _T("ASSETS"), CStdStringW(m_TempPath + _T("\\") + s150x150img_VFSpath.c_str()).c_str()))
648 | {
649 | result = UAPPX_UNEXPECTED_MODULE_RESOURCE_ERROR;
650 | break;
651 | }
652 | }
653 |
654 | // Application 44x44 asset image
655 | CStdStringW s44x44img_VFSpath(_T(""));
656 | s44x44img_VFSpath.Format(_T("Assets\\%s.44x44.png"), shortCut.m_sName);
657 |
658 | if (icon.Load(sImageFile.c_str(), iDx, 44, 44))
659 | {
660 | bIconDone = icon.SaveAsPng(CStdStringW(m_TempPath + _T("\\") + s44x44img_VFSpath.c_str()).c_str());
661 | }
662 |
663 | if (!bIconDone)
664 | {
665 | if (!g_ExtractModuleResource(IDR_ASSETS_44, _T("ASSETS"), CStdStringW(m_TempPath + _T("\\") + s44x44img_VFSpath.c_str()).c_str()))
666 | {
667 | result = UAPPX_UNEXPECTED_MODULE_RESOURCE_ERROR;
668 | break;
669 | }
670 | }
671 |
672 | //Add Application node to AppManifest
673 | CAssociation association = file.GetAssociation();
674 |
675 | if (association.m_vExt.size() > 0)
676 | {
677 | // Create Extension logo asset image if an icon file has been provided.
678 | if (!association.m_sIconfile.IsEmpty())
679 | {
680 | // Extension 150x150 asset image
681 | association.m_sIconVFSpath.Format(_T("Assets\\%s.ExtLogo150x150.png"), shortCut.m_sName);
682 |
683 | sImageFile = association.m_sIconfile;
684 | iDx = association.m_iconIdx;
685 |
686 | if (icon.Load(sImageFile.c_str(), iDx, 150, 150))
687 | {
688 | bIconDone = icon.SaveAsPng(CStdStringW(m_TempPath + _T("\\") + association.m_sIconVFSpath.c_str()).c_str());
689 |
690 | if (!bIconDone)
691 | {
692 | // Icon not found, delete the "m_sIconVFSpath".
693 | // This will cause the Extsion logo to be not adeded to the manifest.
694 | association.m_sIconVFSpath.clear();
695 | }
696 | }
697 | }
698 | }
699 |
700 | result = m_appManifest.SetApplicationNode(shortCut, file.GetVFSpath(), s150x150img_VFSpath.c_str(), s44x44img_VFSpath.c_str(), association);
701 | }
702 |
703 | } while (FALSE);
704 |
705 | return result;
706 | }
707 |
708 | UINT CAppx::FinalizeAppManifest()
709 | {
710 | UINT result = UAPPX_SUCCESS;
711 |
712 | do
713 | {
714 | result = m_appManifest.Do(m_sAuthenticodeCert, m_sAuthenticodeCertPwd);
715 |
716 | } while (FALSE);
717 |
718 | return result;
719 | }
720 |
721 | UINT CAppx::FinalizeAppXcontainer()
722 | {
723 | UINT result = UAPPX_SUCCESS;
724 |
725 | do
726 | {
727 | CStdStringW sExecutable(_T(""));
728 | CStdStringW sCmdLine(_T(""));
729 | CStdStringW sOutAppx(_T(""));
730 |
731 | // Create target directory
732 | if (!DF_DirExist(m_PackagePath.c_str()))
733 | {
734 | if (!DF_CreateDirectory(m_PackagePath.c_str(), NULL))
735 | {
736 | result = UAPPX_FILE_ACCESS_ERROR;
737 | break;
738 | }
739 | }
740 |
741 | sOutAppx.Format(_T("%s.appx"), m_PackagePath + _T("\\") + m_packageName);
742 | DF_DeleteFile(sOutAppx.c_str());
743 |
744 | sExecutable.Format(_T("%s\\%s"), m_winSdkPath, _T("makeappx.exe"));
745 | sCmdLine.Format(_T("\"%s\" pack /d \"%s\" /p \"%s\""), sExecutable, m_TempPath, sOutAppx);
746 |
747 | LPTSTR lpwCmdLine = sCmdLine.GetBuffer();
748 | DWORD dwRet = g_StartProcess(lpwCmdLine);
749 | sCmdLine.ReleaseBuffer();
750 |
751 | if (dwRet != ERROR_SUCCESS)
752 | {
753 | result = UAPPX_CREATE_CONTAINER_ERROR;
754 | break;
755 | }
756 |
757 | // Sign the Package, if a certificate file has been provided.
758 | if (!m_sAuthenticodeCert.IsEmpty())
759 | {
760 | sExecutable.Format(_T("%s\\%s"), m_winSdkPath, _T("signtool.exe"));
761 |
762 | if (!m_sAuthenticodeCertPwd.IsEmpty())
763 | {
764 | if(m_sAuthenticodeTimestamp.IsEmpty())
765 | sCmdLine.Format(_T("\"%s\" sign -f \"%s\" -fd SHA256 -v /p %s \"%s\""), sExecutable, m_sAuthenticodeCert, m_sAuthenticodeCertPwd, sOutAppx);
766 | else
767 | sCmdLine.Format(_T("\"%s\" sign -f \"%s\" /t \"%s\" -fd SHA256 -v /p %s \"%s\""), sExecutable, m_sAuthenticodeCert, m_sAuthenticodeTimestamp, m_sAuthenticodeCertPwd, sOutAppx);
768 | }
769 | else
770 | {
771 | if (m_sAuthenticodeTimestamp.IsEmpty())
772 | sCmdLine.Format(_T("\"%s\" sign -f \"%s\" -fd SHA256 -v \"%s\""), sExecutable, m_sAuthenticodeCert, sOutAppx);
773 | else
774 | sCmdLine.Format(_T("\"%s\" sign -f \"%s\" /t \"%s\" -fd SHA256 -v \"%s\""), sExecutable, m_sAuthenticodeCert, m_sAuthenticodeTimestamp, sOutAppx);
775 | }
776 |
777 | lpwCmdLine = sCmdLine.GetBuffer();
778 | DWORD dwRet = g_StartProcess(lpwCmdLine);
779 | sCmdLine.ReleaseBuffer();
780 |
781 | if (dwRet != ERROR_SUCCESS)
782 | {
783 | result = UAPPX_SIGN_ERROR;
784 | }
785 | }
786 |
787 | } while (FALSE);
788 |
789 | return result;
790 | }
791 |
--------------------------------------------------------------------------------
/IaUwpAppx/CAppx.h:
--------------------------------------------------------------------------------
1 | // FILE: CAppx.h
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #pragma once
29 |
30 | class CAppx
31 | {
32 | public:
33 | CAppx(LPCWSTR lpPackagename, LPCWSTR lpPackagepath, bool b64BitPackage);
34 | ~CAppx(void);
35 |
36 | UINT Initialize();
37 |
38 | void AddVRegKey(CVirtualRegKey& vKey);
39 | UINT AddFile(LPCWSTR lpwSource, LPCWSTR lpwTarget, size_t* pFileIdx);
40 | UINT AddDirectory(LPCWSTR lpwTarget, size_t* pFileIdx);
41 |
42 | UINT AddShortcut(size_t fileIdx, LPCWSTR lpwName, LPCWSTR lpwDescription, LPCWSTR lpwPath, LPCWSTR lpwCommandline, PCWSTR lpwIconfile, int iconIdx);
43 | UINT SetFileAssociation(size_t fileIdx, LPCWSTR lpwProgId, LPCWSTR lpwDescription, LPCWSTR** lpwExtensions, size_t extSize, LPCWSTR lpwIconfile, int iconIdx);
44 | UINT ProcessPackage(void);
45 |
46 | UINT SetDisplayName(LPCWSTR lpwValue);
47 | UINT SetLanguage(LPCWSTR lpwValue);
48 | UINT SetPublisherCertificate(LPCWSTR lpwCertificate, LPCWSTR lpwPassword, LPCWSTR lpwTimestamp);
49 | UINT SetPublisher(LPCWSTR lpwValue);
50 | UINT SetVersion(LPCWSTR lpwValue);
51 |
52 | bool SetWinSdkBinPath(LPCWSTR lpwBinPath);
53 |
54 | protected:
55 | CStdStringW m_winSdkPath;
56 | CStdStringW m_packageName;
57 | CStdStringW m_PackagePath;
58 | CStdStringW m_TempPath;
59 | bool m_b64BitPackage;
60 |
61 | vector m_vVfsPaths;
62 | vector m_vRegkeyList;
63 | vector m_vFileList;
64 |
65 | CAppManifest m_appManifest;
66 |
67 | // Authenticode
68 | CStdStringW m_sAuthenticodeCert;
69 | CStdStringW m_sAuthenticodeCertPwd;
70 | CStdStringW m_sAuthenticodeTimestamp;
71 |
72 | // Used to check if at least a shortcut has been defined
73 | bool m_packageHasShortcut;
74 |
75 | protected:
76 | UINT FinalizeRegistry(void);
77 | UINT FinalizeVirtualFileSystem(void);
78 | UINT FinalizeAssets();
79 | UINT FinalizeAppManifest();
80 | UINT FinalizeAppXcontainer();
81 | };
82 |
--------------------------------------------------------------------------------
/IaUwpAppx/IaUwpAppx.cpp:
--------------------------------------------------------------------------------
1 | // FILE: AppManifest.cpp
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #include "stdafx.h"
29 | #include "IaUwpAppxApp.h"
30 | #include "IaUwpAppx.h"
31 | #include "CAppx.h"
32 |
33 | CAppx* pAppx = NULL;
34 |
35 | UINT __stdcall UAPPX_Initialize(LPCWSTR lpwPackagename, LPCWSTR lpwPackagepath, bool b64BitPackage)
36 | {
37 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
38 |
39 | UINT result = UAPPX_FAILURE;
40 |
41 | do
42 | {
43 | if (!lpwPackagename || !lpwPackagepath)
44 | {
45 | result = UAPPX_PARAM_ERROR;
46 | break;
47 | }
48 |
49 | UAPPX_Free();
50 |
51 | pAppx = new CAppx(lpwPackagename, lpwPackagepath, b64BitPackage);
52 | if (!pAppx)
53 | {
54 | result = UAPPX_OUT_OF_MEMORY_ERROR;
55 | break;
56 | }
57 |
58 | result = pAppx->Initialize();
59 |
60 | } while (FALSE);
61 |
62 | return result;
63 | }
64 |
65 | void __stdcall UAPPX_Free()
66 | {
67 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
68 |
69 | if (pAppx)
70 | {
71 | delete pAppx;
72 | pAppx = NULL;
73 | }
74 | }
75 |
76 | //////////////////////////////////////////////////////////
77 | UINT __stdcall UAPPX_SetDisplayName(LPCWSTR lpwValue)
78 | {
79 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
80 |
81 | UINT result = UAPPX_FAILURE;
82 |
83 | do
84 | {
85 | if (!pAppx)
86 | {
87 | result = UAPPX_NOT_INITIALIZED;
88 | break;
89 | }
90 |
91 | result = pAppx->SetDisplayName(lpwValue);
92 |
93 | } while (FALSE);
94 |
95 | return result;
96 | }
97 |
98 | UINT __stdcall UAPPX_SetLanguage(LPCWSTR lpwValue)
99 | {
100 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
101 |
102 | UINT result = UAPPX_FAILURE;
103 |
104 | do
105 | {
106 | if (!pAppx)
107 | {
108 | result = UAPPX_NOT_INITIALIZED;
109 | break;
110 | }
111 |
112 | result = pAppx->SetLanguage(lpwValue);
113 |
114 | } while (FALSE);
115 |
116 | return result;
117 | }
118 |
119 | UINT __stdcall UAPPX_SetPublisherCertificate(LPCWSTR lpwCertificate, LPCWSTR lpwPassword, LPCWSTR lpwTimestamp)
120 | {
121 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
122 |
123 | UINT result = UAPPX_FAILURE;
124 |
125 | do
126 | {
127 | if (!pAppx)
128 | {
129 | result = UAPPX_NOT_INITIALIZED;
130 | break;
131 | }
132 |
133 | result = pAppx->SetPublisherCertificate(lpwCertificate, lpwPassword, lpwTimestamp);
134 |
135 | } while (FALSE);
136 |
137 | return result;
138 | }
139 |
140 | UINT __stdcall UAPPX_SetPublisher(LPCWSTR lpwValue)
141 | {
142 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
143 |
144 | UINT result = UAPPX_FAILURE;
145 |
146 | do
147 | {
148 | if (!pAppx)
149 | {
150 | result = UAPPX_NOT_INITIALIZED;
151 | break;
152 | }
153 |
154 | result = pAppx->SetPublisher(lpwValue);
155 |
156 | } while (FALSE);
157 |
158 | return result;
159 | }
160 |
161 | UINT __stdcall UAPPX_SetVersion(LPCWSTR lpwValue)
162 | {
163 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
164 |
165 | UINT result = UAPPX_FAILURE;
166 |
167 | do
168 | {
169 | if (!pAppx)
170 | {
171 | result = UAPPX_NOT_INITIALIZED;
172 | break;
173 | }
174 |
175 | result = pAppx->SetVersion(lpwValue);
176 |
177 | } while (FALSE);
178 |
179 | return result;
180 | }
181 |
182 | //////////////////////////////////////////////////////////
183 | UINT __stdcall UAPPX_SetVirtualRegistryKey(HKEY hKey, LPCWSTR lpwSubKey, DWORD dwType, LPCWSTR lpwValueName, LPVOID lpwValue, DWORD dwSize, bool bWin32)
184 | {
185 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
186 |
187 | UINT result = UAPPX_SUCCESS;
188 |
189 | do
190 | {
191 | if (!pAppx)
192 | {
193 | result = UAPPX_NOT_INITIALIZED;
194 | break;
195 | }
196 |
197 | CVirtualRegKey key;
198 | result = key.Set(hKey, lpwSubKey, dwType, lpwValueName, lpwValue, dwSize, bWin32);
199 |
200 | if (result != UAPPX_SUCCESS)
201 | break;
202 |
203 | pAppx->AddVRegKey(key);
204 |
205 | } while (FALSE);
206 |
207 | return result;
208 | }
209 |
210 | UINT __stdcall UAPPX_SetPackageFile(LPCWSTR lpwSource, LPCWSTR lpwTarget, size_t* pFileIdx)
211 | {
212 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
213 |
214 | UINT result = UAPPX_FAILURE;
215 |
216 | do
217 | {
218 | if (!pAppx)
219 | {
220 | result = UAPPX_NOT_INITIALIZED;
221 | break;
222 | }
223 |
224 | result = pAppx->AddFile(lpwSource, lpwTarget, pFileIdx);
225 |
226 | } while (FALSE);
227 |
228 | return result;
229 | }
230 |
231 | UINT __stdcall UAPPX_SetPackageDirectory(LPCWSTR lpwTarget, size_t* pFileIdx)
232 | {
233 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
234 |
235 | UINT result = UAPPX_FAILURE;
236 |
237 | do
238 | {
239 | if (!pAppx)
240 | {
241 | result = UAPPX_NOT_INITIALIZED;
242 | break;
243 | }
244 |
245 | result = pAppx->AddDirectory(lpwTarget, pFileIdx);
246 |
247 | } while (FALSE);
248 |
249 | return result;
250 | }
251 |
252 | UINT __stdcall UAPPX_SetFileAssociation(size_t fileIdx, LPCWSTR lpwProgId, LPCWSTR lpwDescription, LPCWSTR** lpwExtensions, size_t extSize, LPCWSTR lpwIconfile, int iconIdx)
253 | {
254 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
255 |
256 | UINT result = UAPPX_FAILURE;
257 |
258 | do
259 | {
260 | if (!pAppx)
261 | {
262 | result = UAPPX_NOT_INITIALIZED;
263 | break;
264 | }
265 |
266 | result = pAppx->SetFileAssociation(fileIdx, lpwProgId, lpwDescription, lpwExtensions, extSize, lpwIconfile, iconIdx);
267 |
268 | } while (FALSE);
269 |
270 | return result;
271 | }
272 |
273 | UINT __stdcall UAPPX_SetShortcut(size_t fileIdx, LPCWSTR lpwName, LPCWSTR lpwDescription, LPCWSTR lpwPath, LPCWSTR lpwCommandline, PCWSTR lpwIconfile, int iconIdx)
274 | {
275 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
276 |
277 | UINT result = UAPPX_FAILURE;
278 |
279 | do
280 | {
281 | if (!pAppx)
282 | {
283 | result = UAPPX_NOT_INITIALIZED;
284 | break;
285 | }
286 |
287 | // NOTE
288 | // lpwIconfile - Icon path can be null
289 | // lpwDescription - Description can be null
290 | // lpwCommandline - CmdLine can be null
291 |
292 | result = pAppx->AddShortcut(fileIdx, lpwName, lpwDescription, lpwPath, lpwCommandline, lpwIconfile, iconIdx);
293 |
294 | } while (FALSE);
295 |
296 | return result;
297 | }
298 |
299 | UINT __stdcall UAPPX_Finalize()
300 | {
301 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
302 |
303 | UINT result = UAPPX_FAILURE;
304 |
305 | do
306 | {
307 | if (!pAppx)
308 | {
309 | result = UAPPX_NOT_INITIALIZED;
310 | break;
311 | }
312 |
313 | result = pAppx->ProcessPackage();
314 |
315 | } while (FALSE);
316 |
317 | return result;
318 | }
319 |
320 | UINT __stdcall UAPPX_SetWinSdkBinPath(LPCWSTR lpwPath)
321 | {
322 | AFX_MANAGE_STATE(AfxGetStaticModuleState());
323 |
324 | UINT result = UAPPX_FAILURE;
325 |
326 | do
327 | {
328 | if (!pAppx)
329 | {
330 | result = UAPPX_NOT_INITIALIZED;
331 | break;
332 | }
333 |
334 | if(pAppx->SetWinSdkBinPath(lpwPath))
335 | {
336 | result = UAPPX_SUCCESS;
337 | }
338 |
339 | } while (FALSE);
340 |
341 | return result;
342 | }
--------------------------------------------------------------------------------
/IaUwpAppx/IaUwpAppx.def:
--------------------------------------------------------------------------------
1 | ; IaUwpAppx.def : Declares the module parameters for the DLL.
2 |
3 | LIBRARY
4 |
5 | EXPORTS
6 | UAPPX_Initialize
7 | UAPPX_Finalize
8 | UAPPX_Free
9 |
10 | UAPPX_SetDisplayName
11 | UAPPX_SetFileAssociation
12 | UAPPX_SetLanguage
13 | UAPPX_SetPackageFile
14 | UAPPX_SetPackageDirectory
15 | UAPPX_SetPublisher
16 | UAPPX_SetPublisherCertificate
17 | UAPPX_SetShortcut
18 | UAPPX_SetVersion
19 | UAPPX_SetVirtualRegistryKey
20 |
21 | UAPPX_SetWinSdkBinPath
--------------------------------------------------------------------------------
/IaUwpAppx/IaUwpAppx.h:
--------------------------------------------------------------------------------
1 | // FILE: IaUwpAppx.h main header file for the IaUwpAppx DLL
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #pragma once
29 |
30 | #if (!defined __IA_UWPAPPX_H)
31 | #define __IA_UWPAPPX_H
32 |
33 | // RETURN CODES
34 | #define UAPPX_SUCCESS 0
35 | #define UAPPX_FAILURE 100
36 | #define UAPPX_NOT_INITIALIZED 101
37 | #define UAPPX_PARAM_ERROR 102
38 | #define UAPPX_OUT_OF_MEMORY_ERROR 103
39 | #define UAPPX_FILE_ACCESS_ERROR 105
40 | #define UAPPX_UNEXPECTED_MODULE_RESOURCE_ERROR 106
41 | #define UAPPX_CERTIFICATE_ERROR 107
42 | #define UAPPX_CERTIFICATE_INVALID_PASSWORD 108
43 | #define UAPPX_CERTIFICATE_FILE_ACCESS_ERROR 109
44 | #define UAPPX_CERTIFICATE_FILE_NOT_FOUND 110
45 |
46 | #define UAPPX_UNSUPPORTED_REGISTRY_VALUE 115
47 |
48 | #define UAPPX_REG_DAT_ERROR 120
49 | #define UAPPX_REG_DAT_SECURITY_DESCRIPTOR_ERROR 121
50 | #define UAPPX_REG_DAT_PRIVILEGE_ERROR 122
51 |
52 | #define UAPPX_SYS_PATHS_ENUM_ERROR 140
53 |
54 | #define UAPPX_SOURCE_FILE_NOT_FOUND 160
55 | #define UAPPX_VFS_PATH_NOT_RESOLVED 161
56 | #define UAPPX_VFSFILE_COPY_ERROR 162
57 | #define UAPPX_VFSASSETS_ERROR 163
58 |
59 | #define UAPPX_CREATE_CONTAINER_ERROR 180
60 |
61 | #define UAPPX_NO_SHORTCUT_DEFINED 185
62 |
63 | #define UAPPX_CREATE_MANIFEST_ERROR 200
64 | #define UAPPX_INVALID_MANIFEST_VALUE 201
65 |
66 | #define UAPPX_SIGN_ERROR 210
67 |
68 |
69 | //EXPORT FUNCTION DECLARATIONs
70 | /////////////////////////////////////////////////////////////////////////////
71 |
72 | #if defined(__cplusplus)
73 | extern "C" {
74 | #endif
75 |
76 | UINT __stdcall UAPPX_Initialize(LPCWSTR lpwPackagename, LPCWSTR lpwPath, bool b64BitPackage);
77 | UINT __stdcall UAPPX_Finalize();
78 | void __stdcall UAPPX_Free();
79 |
80 | UINT __stdcall UAPPX_SetDisplayName(LPCWSTR lpwValue);
81 |
82 | // UAPPX_SetFileAssociation Notes!
83 | // With the current implementation only the prameters; "fileIdx", "lpwExtensions" and "extSize" are used.
84 | // The remaining parameters are not used by the library and these are present for "a possible" implementation in successive versions.
85 | UINT __stdcall UAPPX_SetFileAssociation(size_t fileIdx, LPCWSTR lpwProgId, LPCWSTR lpwDescription, LPCWSTR** lpwExtensions, size_t extSize, LPCWSTR lpwIconfile, int iconIdx);
86 |
87 | UINT __stdcall UAPPX_SetLanguage(LPCWSTR lpwValue);
88 |
89 | UINT __stdcall UAPPX_SetPackageFile(LPCWSTR lpwSource, LPCWSTR lpwTarget, size_t* pFileIdx);
90 | UINT __stdcall UAPPX_SetPackageDirectory(LPCWSTR lpwTarget, size_t* pFileIdx);
91 |
92 | UINT __stdcall UAPPX_SetPublisher(LPCWSTR lpwValue);
93 | UINT __stdcall UAPPX_SetPublisherCertificate(LPCWSTR lpwCertificate, LPCWSTR lpwPassword, LPCWSTR lpwTimestamp);
94 |
95 | // UAPPX_SetShortcut Notes!
96 | // Parameters; lpwDescription, lpwPath, pwCommandline and lpwIconfile can be NULL.
97 | //
98 | // With the current implementation only the prameters; "fileIdx", "lpwName" and "lpwDescription" are used.
99 | // The remaining parameters are not used by the library and these are present for "a possible" implementation in successive versions.
100 | UINT __stdcall UAPPX_SetShortcut(size_t fileIdx, LPCWSTR lpwName, LPCWSTR lpwDescription, LPCWSTR lpwPath, LPCWSTR lpwCommandline, PCWSTR lpwIconfile, int iconIdx);
101 |
102 | UINT __stdcall UAPPX_SetVersion(LPCWSTR lpwValue);
103 | UINT __stdcall UAPPX_SetVirtualRegistryKey(HKEY hKey, LPCWSTR lpwSubKey, DWORD dwType, LPCWSTR lpwValueName, LPVOID lpValue, DWORD dwSize, bool bWin32);
104 |
105 | UINT __stdcall UAPPX_SetWinSdkBinPath(LPCWSTR lpwPath);
106 |
107 | #if defined(__cplusplus)
108 | }
109 | #endif
110 | /////////////////////////////////////////////////////////////////////////////
111 |
112 | #endif // __IA_UWPAPPX_H
113 |
--------------------------------------------------------------------------------
/IaUwpAppx/IaUwpAppx.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/IaUwpAppx.rc
--------------------------------------------------------------------------------
/IaUwpAppx/IaUwpAppx.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25123.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IaUwpAppx", "IaUwpAppx.vcxproj", "{F84AB17A-00DB-4961-9628-592E3175535E}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {F84AB17A-00DB-4961-9628-592E3175535E}.Debug|x64.ActiveCfg = Debug|x64
17 | {F84AB17A-00DB-4961-9628-592E3175535E}.Debug|x64.Build.0 = Debug|x64
18 | {F84AB17A-00DB-4961-9628-592E3175535E}.Debug|x86.ActiveCfg = Debug|Win32
19 | {F84AB17A-00DB-4961-9628-592E3175535E}.Debug|x86.Build.0 = Debug|Win32
20 | {F84AB17A-00DB-4961-9628-592E3175535E}.Release|x64.ActiveCfg = Release|x64
21 | {F84AB17A-00DB-4961-9628-592E3175535E}.Release|x64.Build.0 = Release|x64
22 | {F84AB17A-00DB-4961-9628-592E3175535E}.Release|x86.ActiveCfg = Release|Win32
23 | {F84AB17A-00DB-4961-9628-592E3175535E}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(TeamFoundationVersionControl) = preSolution
29 | SccNumberOfProjects = 2
30 | SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
31 | SccTeamFoundationServer = http://phenomii-x64x4:8080/tfs/sinan%20projects
32 | SccProjectUniqueName0 = IaUwpAppx.vcxproj
33 | SccLocalPath0 = .
34 | SccLocalPath1 = .
35 | EndGlobalSection
36 | EndGlobal
37 |
--------------------------------------------------------------------------------
/IaUwpAppx/IaUwpAppx.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 | {F84AB17A-00DB-4961-9628-592E3175535E}
23 | IaUwpAppx
24 | 8.1
25 | MFCDLLProj
26 | SAK
27 | SAK
28 | SAK
29 | SAK
30 | IaUwpAppx
31 |
32 |
33 |
34 | DynamicLibrary
35 | true
36 | v140
37 | Unicode
38 | Static
39 |
40 |
41 | DynamicLibrary
42 | false
43 | v140
44 | false
45 | Unicode
46 | Static
47 |
48 |
49 | DynamicLibrary
50 | true
51 | v140
52 | Unicode
53 | Static
54 |
55 |
56 | DynamicLibrary
57 | false
58 | v140
59 | false
60 | Unicode
61 | Static
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | true
83 | $(PlatformToolset)\$(Platform)\$(Configuration)\
84 | $(PlatformToolset)\$(Platform)\$(Configuration)\
85 | .\libs;$(IncludePath)
86 | .\libs;$(LibraryPath)
87 |
88 |
89 | true
90 | $(PlatformToolset)\$(Platform)\$(Configuration)\
91 | $(PlatformToolset)\$(Platform)\$(Configuration)\
92 | $(ProjectName)64
93 | .\libs;$(IncludePath)
94 | .\libs;$(LibraryPath)
95 |
96 |
97 | false
98 | .\bin x86\
99 | $(PlatformToolset)\$(Platform)\$(Configuration)\
100 | .\libs;$(IncludePath)
101 | .\libs;$(LibraryPath)
102 |
103 |
104 | false
105 | .\bin x64\
106 | $(PlatformToolset)\$(Platform)\$(Configuration)\
107 | .\libs;$(IncludePath)
108 | .\libs;$(LibraryPath)
109 | $(ProjectName)64
110 |
111 |
112 |
113 | Use
114 | Level3
115 | Disabled
116 | WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)
117 | true
118 |
119 |
120 | Windows
121 | .\IaUwpAppx.def
122 | Rpcrt4.lib;DFRegistry.lib;dffileop.lib
123 | 6.03
124 |
125 |
126 | false
127 | _DEBUG;%(PreprocessorDefinitions)
128 |
129 |
130 | 0x0409
131 | _DEBUG;%(PreprocessorDefinitions)
132 | $(IntDir);%(AdditionalIncludeDirectories)
133 |
134 |
135 |
136 |
137 | Use
138 | Level3
139 | Disabled
140 | _WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)
141 | true
142 |
143 |
144 | Windows
145 | .\IaUwpAppx.def
146 | Rpcrt4.lib;DFRegistry64.lib;dffileop64.lib
147 | 6.03
148 |
149 |
150 | false
151 | _DEBUG;%(PreprocessorDefinitions)
152 |
153 |
154 | 0x0409
155 | _DEBUG;%(PreprocessorDefinitions)
156 | $(IntDir);%(AdditionalIncludeDirectories)
157 |
158 |
159 |
160 |
161 | Level3
162 | Use
163 | MaxSpeed
164 | true
165 | true
166 | WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)
167 | true
168 |
169 |
170 |
171 | Windows
172 | true
173 | true
174 | .\IaUwpAppx.def
175 | No
176 | Rpcrt4.lib;DFRegistry.lib;dffileop.lib
177 | 6.03
178 |
179 |
180 | false
181 | NDEBUG;%(PreprocessorDefinitions)
182 |
183 |
184 | 0x0409
185 | NDEBUG;%(PreprocessorDefinitions)
186 | $(IntDir);%(AdditionalIncludeDirectories)
187 |
188 |
189 |
190 |
191 | Level3
192 | Use
193 | MaxSpeed
194 | true
195 | true
196 | _WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)
197 | true
198 |
199 |
200 |
201 | Windows
202 | true
203 | true
204 | .\IaUwpAppx.def
205 | No
206 | Rpcrt4.lib;DFRegistry64.lib;dffileop64.lib
207 | 6.03
208 |
209 |
210 | false
211 | NDEBUG;%(PreprocessorDefinitions)
212 |
213 |
214 | 0x0409
215 | NDEBUG;%(PreprocessorDefinitions)
216 | $(IntDir);%(AdditionalIncludeDirectories)
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 | Create
229 | Create
230 | Create
231 | Create
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
--------------------------------------------------------------------------------
/IaUwpAppx/IaUwpAppx.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 |
18 |
19 | Source Files
20 |
21 |
22 | Source Files
23 |
24 |
25 | Source Files
26 |
27 |
28 | Source Files
29 |
30 |
31 | Source Files
32 |
33 |
34 | Source Files
35 |
36 |
37 | Source Files
38 |
39 |
40 | Source Files
41 |
42 |
43 | Source Files
44 |
45 |
46 |
47 |
48 | Header Files
49 |
50 |
51 | Header Files
52 |
53 |
54 | Header Files
55 |
56 |
57 | Header Files
58 |
59 |
60 | Header Files
61 |
62 |
63 | Header Files
64 |
65 |
66 | Header Files
67 |
68 |
69 | Header Files
70 |
71 |
72 | Header Files
73 |
74 |
75 | Header Files
76 |
77 |
78 | Header Files
79 |
80 |
81 | Header Files
82 |
83 |
84 |
85 |
86 | Source Files
87 |
88 |
89 | Resource Files
90 |
91 |
92 |
93 |
94 | Resource Files
95 |
96 |
97 | Resource Files
98 |
99 |
100 | Resource Files
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | Resource Files
109 |
110 |
111 |
--------------------------------------------------------------------------------
/IaUwpAppx/IaUwpAppxApp.cpp:
--------------------------------------------------------------------------------
1 | // FILE: IaUwpAppx.cpp : Defines the initialization routines for the DLL.
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #include "stdafx.h"
29 | #include "IaUwpAppxApp.h"
30 | #include "IaUwpAppx.h"
31 |
32 | #ifdef _DEBUG
33 | #define new DEBUG_NEW
34 | #endif
35 |
36 | //
37 | //TODO: If this DLL is dynamically linked against the MFC DLLs,
38 | // any functions exported from this DLL which call into
39 | // MFC must have the AFX_MANAGE_STATE macro added at the
40 | // very beginning of the function.
41 | //
42 | // For example:
43 | //
44 | // extern "C" BOOL PASCAL EXPORT ExportedFunction()
45 | // {
46 | // AFX_MANAGE_STATE(AfxGetStaticModuleState());
47 | // // normal function body here
48 | // }
49 | //
50 | // It is very important that this macro appear in each
51 | // function, prior to any calls into MFC. This means that
52 | // it must appear as the first statement within the
53 | // function, even before any object variable declarations
54 | // as their constructors may generate calls into the MFC
55 | // DLL.
56 | //
57 | // Please see MFC Technical Notes 33 and 58 for additional
58 | // details.
59 | //
60 |
61 | // CIaUwpAppxApp
62 |
63 | BEGIN_MESSAGE_MAP(CIaUwpAppxApp, CWinApp)
64 | END_MESSAGE_MAP()
65 |
66 |
67 | // CIaUwpAppxApp construction
68 |
69 | CIaUwpAppxApp::CIaUwpAppxApp()
70 | {
71 | // TODO: add construction code here,
72 | // Place all significant initialization in InitInstance
73 | }
74 |
75 |
76 | // The one and only CIaUwpAppxApp object
77 | CIaUwpAppxApp theApp;
78 |
79 |
80 | // CIaUwpAppxApp initialization
81 |
82 | BOOL CIaUwpAppxApp::InitInstance()
83 | {
84 | CWinApp::InitInstance();
85 |
86 | // Initialize COM
87 | //CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
88 |
89 | return TRUE;
90 | }
91 |
92 | int CIaUwpAppxApp::ExitInstance()
93 | {
94 | // TODO: Add your specialized code here and/or call the base class
95 | //CoUninitialize();
96 |
97 | return CWinApp::ExitInstance();
98 | }
99 |
--------------------------------------------------------------------------------
/IaUwpAppx/IaUwpAppxApp.h:
--------------------------------------------------------------------------------
1 | // FILE: IaUwpAppxApp.h
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #pragma once
29 |
30 | #ifndef __AFXWIN_H__
31 | #error "include 'stdafx.h' before including this file for PCH"
32 | #endif
33 |
34 | #include "resource.h" // main symbols
35 |
36 | #include "VirtualRegKey.h"
37 | #include "PackageFile.h"
38 | #include "AppManifest.h"
39 | // CIaUwpAppxApp
40 | // See IaUwpAppx.cpp for the implementation of this class
41 | //
42 |
43 | class CIaUwpAppxApp : public CWinApp
44 | {
45 | public:
46 | CIaUwpAppxApp();
47 |
48 | // Overrides
49 | public:
50 | virtual BOOL InitInstance();
51 |
52 | DECLARE_MESSAGE_MAP()
53 | virtual int ExitInstance();
54 | };
55 |
56 | extern CIaUwpAppxApp theApp;
--------------------------------------------------------------------------------
/IaUwpAppx/IconExt.cpp:
--------------------------------------------------------------------------------
1 | // FILE: IconExt.cpp
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #include "stdafx.h"
29 | #include "IconExt.h"
30 |
31 |
32 | #include
33 | #include
34 | #include
35 | #include
36 |
37 | _COM_SMARTPTR_TYPEDEF(IImageList, __uuidof(IImageList));
38 |
39 | struct BITMAP_AND_BYTES
40 | {
41 | Gdiplus::Bitmap* bmp;
42 | int32_t* bytes;
43 | };
44 |
45 | static CLSID g_pngClsid = GUID_NULL;
46 | /////////////////////////////////
47 | static int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
48 | {
49 | UINT num = 0; // number of image encoders
50 | UINT size = 0; // size of the image encoder array in bytes
51 |
52 | ImageCodecInfo* pImageCodecInfo = NULL;
53 |
54 | GetImageEncodersSize(&num, &size);
55 | if (size == 0)
56 | return -1; // Failure
57 |
58 | pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
59 | if (pImageCodecInfo == NULL)
60 | return -1; // Failure
61 |
62 | GetImageEncoders(num, size, pImageCodecInfo);
63 |
64 | for (UINT j = 0; j < num; ++j)
65 | {
66 | if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
67 | {
68 | *pClsid = pImageCodecInfo[j].Clsid;
69 | free(pImageCodecInfo);
70 | return j; // Success
71 | }
72 | }
73 |
74 | free(pImageCodecInfo);
75 | return -1; // Failure
76 | }
77 |
78 | static BITMAP_AND_BYTES CreateAlphaChannelBitmapFromIcon(HICON hIcon)
79 | {
80 | // Get the icon info
81 | ICONINFO iconInfo = { 0 };
82 | GetIconInfo(hIcon, &iconInfo);
83 |
84 | // Get the screen DC
85 | HDC dc = GetDC(NULL);
86 |
87 | // Get icon size info
88 | BITMAP bm = { 0 };
89 | GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bm);
90 |
91 | // Set up BITMAPINFO
92 | BITMAPINFO bmi = { 0 };
93 | bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
94 | bmi.bmiHeader.biWidth = bm.bmWidth;
95 | bmi.bmiHeader.biHeight = -bm.bmHeight;
96 | bmi.bmiHeader.biPlanes = 1;
97 | bmi.bmiHeader.biBitCount = 32;
98 | bmi.bmiHeader.biCompression = BI_RGB;
99 |
100 | // Extract the color bitmap
101 | int nBits = bm.bmWidth * bm.bmHeight;
102 | int32_t* colorBits = new int32_t[nBits];
103 | GetDIBits(dc, iconInfo.hbmColor, 0, bm.bmHeight, colorBits, &bmi, DIB_RGB_COLORS);
104 |
105 | // Check whether the color bitmap has an alpha channel.
106 | // (On my Windows 7, all file icons I tried have an alpha channel.)
107 | BOOL hasAlpha = FALSE;
108 | for (int i = 0; i < nBits; i++)
109 | {
110 | if ((colorBits[i] & 0xff000000) != 0)
111 | {
112 | hasAlpha = TRUE;
113 | break;
114 | }
115 | }
116 |
117 | // If no alpha values available, apply the mask bitmap
118 | if (!hasAlpha)
119 | {
120 | // Extract the mask bitmap
121 | int32_t* maskBits = new int32_t[nBits];
122 | GetDIBits(dc, iconInfo.hbmMask, 0, bm.bmHeight, maskBits, &bmi, DIB_RGB_COLORS);
123 | // Copy the mask alphas into the color bits
124 | for (int i = 0; i < nBits; i++)
125 | {
126 | if (maskBits[i] == 0)
127 | {
128 | colorBits[i] |= 0xff000000;
129 | }
130 | }
131 | delete[] maskBits;
132 | }
133 |
134 | // Release DC and GDI bitmaps
135 | ReleaseDC(NULL, dc);
136 | ::DeleteObject(iconInfo.hbmColor);
137 | ::DeleteObject(iconInfo.hbmMask);
138 |
139 | // Create GDI+ Bitmap
140 | Gdiplus::Bitmap* bmp = new Gdiplus::Bitmap(bm.bmWidth, bm.bmHeight, bm.bmWidth * 4, PixelFormat32bppARGB, (BYTE*)colorBits);
141 | BITMAP_AND_BYTES ret = { bmp, colorBits };
142 |
143 | return ret;
144 | }
145 | /////////////////////////////////////////////////////
146 |
147 | CIconExt::CIconExt()
148 | {
149 | m_gdiplusToken = NULL;
150 | GdiplusStartupInput gdiplusStartupInput;
151 | GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
152 |
153 | m_bmp = NULL;
154 | }
155 |
156 | CIconExt::~CIconExt()
157 | {
158 | Free();
159 |
160 | GdiplusShutdown(m_gdiplusToken);
161 | }
162 |
163 | void CIconExt::Free()
164 | {
165 | if (m_bmp)
166 | delete m_bmp;
167 |
168 | m_bmp = NULL;
169 | }
170 |
171 | bool CIconExt::Load(LPCWSTR lpwPath, int index, int nWidth, int nHeight)
172 | {
173 | bool result = false;
174 |
175 | if (!lpwPath)
176 | return result;
177 |
178 | Free();
179 |
180 | HICON hIcon = NULL;
181 |
182 | do
183 | {
184 | CStdStringW sPath(lpwPath);
185 | CStdStringW sExt(_T(""));
186 |
187 | size_t nSize = 0;
188 | if (DF_GetFileExt(lpwPath, NULL, &nSize))
189 | {
190 | nSize += 1;
191 | LPWSTR p = sExt.GetBuffer((int)nSize);
192 | DF_GetFileExt(lpwPath, p, &nSize);
193 | sExt.ReleaseBuffer();
194 | }
195 |
196 | if (0 == sExt.CompareNoCase(_T("ico")))
197 | {
198 | hIcon = (HICON)LoadImage(0, lpwPath, IMAGE_ICON, nWidth, nHeight, LR_LOADFROMFILE | LR_LOADMAP3DCOLORS);
199 |
200 | if (hIcon)
201 | {
202 | break;
203 | }
204 | }
205 |
206 | hIcon = GetExtraLargeIcon(lpwPath, index);
207 |
208 | } while (FALSE);
209 |
210 | if (hIcon)
211 | {
212 | BITMAP_AND_BYTES bbs = CreateAlphaChannelBitmapFromIcon(hIcon);
213 |
214 | if (bbs.bmp && bbs.bytes)
215 | {
216 | //Resize
217 | int w = bbs.bmp->GetWidth();
218 | int h = bbs.bmp->GetHeight();
219 |
220 | if (w != nWidth || h != nHeight)
221 | {
222 | float wFactor = (float)nWidth / (float)w;
223 | float hFactor = (float)nHeight / (float)h;
224 |
225 | m_bmp = new Gdiplus::Bitmap((int)nWidth, (int)nHeight);
226 |
227 | Graphics g(m_bmp);
228 | g.ScaleTransform(wFactor, hFactor);
229 | g.DrawImage(bbs.bmp, 0, 0);
230 | }
231 | else
232 | {
233 | m_bmp = new Gdiplus::Bitmap((int)nWidth, (int)nHeight);
234 | Graphics g(m_bmp);
235 | g.DrawImage(bbs.bmp, 0, 0);
236 | }
237 |
238 | result = true;
239 | }
240 |
241 | if (bbs.bmp)
242 | delete bbs.bmp;
243 | if(bbs.bytes)
244 | delete[] bbs.bytes;
245 | }
246 |
247 | if (hIcon)
248 | ::DestroyIcon(hIcon);
249 |
250 | return result;
251 | }
252 |
253 | HICON CIconExt::GetExtraLargeIcon(LPCWSTR lpwPath, int index)
254 | {
255 | HICON hIcon = NULL;
256 |
257 | if (!lpwPath)
258 | return hIcon;
259 |
260 | do
261 | {
262 | SHFILEINFO sfi;
263 |
264 | if (!SHGetFileInfo(lpwPath, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX))
265 | break;
266 |
267 | // Get the extralarge image list
268 | IImageList *piml;
269 | if (FAILED(SHGetImageList(SHIL_JUMBO, IID_PPV_ARGS(&piml))))
270 | break;
271 |
272 | // Extract the icon
273 | if (index < 0)
274 | index = sfi.iIcon;
275 |
276 | piml->GetIcon(index, ILD_NORMAL, &hIcon);
277 |
278 | // Clean up
279 | piml->Release();
280 |
281 | } while (FALSE);
282 |
283 | return hIcon;
284 | }
285 |
286 | bool CIconExt::SaveAsPng(LPCWSTR lpwFile)
287 | {
288 | bool result = false;
289 |
290 | if (!m_bmp)
291 | return result;
292 | if(!lpwFile)
293 | return result;
294 |
295 | do
296 | {
297 | IStream* fstrm = NULL;
298 | if (FAILED(SHCreateStreamOnFile(lpwFile, STGM_WRITE | STGM_CREATE, &fstrm)))
299 | break;
300 |
301 | GetEncoderClsid(L"image/png", &g_pngClsid);
302 | Status stat = m_bmp->Save(fstrm, &g_pngClsid, NULL);
303 |
304 | if (stat == Ok)
305 | result = true;
306 |
307 | fstrm->Release();
308 |
309 | } while (FALSE);
310 |
311 | return result;
312 | }
--------------------------------------------------------------------------------
/IaUwpAppx/IconExt.h:
--------------------------------------------------------------------------------
1 | // FILE: IconExt.h
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #pragma once
29 |
30 | #include
31 | using namespace Gdiplus;
32 |
33 | class CIconExt
34 | {
35 | public:
36 | CIconExt();
37 | ~CIconExt();
38 |
39 | void Free();
40 |
41 | bool Load(LPCWSTR lpwPath, int index, int nWidth, int nHeight);
42 | static HICON GetExtraLargeIcon(LPCWSTR lpwPath, int index);
43 |
44 | bool CIconExt::SaveAsPng(LPCWSTR lpwFile);
45 |
46 | protected:
47 | Gdiplus::Bitmap* m_bmp;
48 | ULONG_PTR m_gdiplusToken;
49 | };
50 |
51 |
--------------------------------------------------------------------------------
/IaUwpAppx/PackageFile.cpp:
--------------------------------------------------------------------------------
1 | // FILE: PackageFile.cpp
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #include "stdafx.h"
29 | #include "IaUwpAppxApp.h"
30 | #include "IaUwpAppx.h"
31 | #include "PackageFile.h"
32 |
33 | bool operator== (const CPackageFile &v1, const CPackageFile &v2)
34 | {
35 | return (v1.m_sSourcePath == v2.m_sSourcePath &&
36 | v1.m_sTargetPath == v2.m_sTargetPath &&
37 | v1.m_sVFSpath == v2.m_sVFSpath);
38 | }
39 |
40 | bool operator!= (CPackageFile &v1, CPackageFile &v2)
41 | {
42 | return !(v1 == v2);
43 | }
44 |
45 | CPackageFile::CPackageFile()
46 | {
47 | m_sSourcePath = _T("");
48 | m_sTargetPath = _T("");
49 | m_sVFSpath = _T("");
50 | }
51 |
52 | CPackageFile::~CPackageFile()
53 | {
54 | }
55 |
56 | UINT CPackageFile::Set(LPCWSTR lpwSource, LPCWSTR lpwTarget, vector& vVfs)
57 | {
58 | UINT result = UAPPX_SUCCESS;
59 |
60 | do
61 | {
62 | if (!lpwSource || !lpwTarget)
63 | {
64 | result = UAPPX_PARAM_ERROR;
65 | break;
66 | }
67 |
68 | if (!DF_FileExist(lpwSource))
69 | {
70 | result = UAPPX_SOURCE_FILE_NOT_FOUND;
71 | break;
72 | }
73 |
74 | m_sSourcePath = lpwSource;
75 | m_sTargetPath = lpwTarget;
76 |
77 | m_sVFSpath = ResolveVFS(lpwTarget, vVfs);
78 |
79 | if (m_sVFSpath.IsEmpty())
80 | result = UAPPX_VFS_PATH_NOT_RESOLVED;
81 |
82 | } while (FALSE);
83 |
84 | return result;
85 | }
86 |
87 | UINT CPackageFile::Set(LPCWSTR lpwTarget, vector& vVfs)
88 | {
89 | UINT result = UAPPX_SUCCESS;
90 |
91 | do
92 | {
93 | if (!lpwTarget)
94 | {
95 | result = UAPPX_PARAM_ERROR;
96 | break;
97 | }
98 |
99 | m_sSourcePath.clear();
100 | m_sTargetPath = lpwTarget;
101 |
102 | m_sVFSpath = ResolveVFS(lpwTarget, vVfs);
103 |
104 | if (m_sVFSpath.IsEmpty())
105 | result = UAPPX_VFS_PATH_NOT_RESOLVED;
106 |
107 | } while (FALSE);
108 |
109 | return result;
110 | }
111 |
112 | CStdStringW CPackageFile::ResolveVFS(LPCWSTR lpwPath, vector& vVfs)
113 | {
114 | CStdStringW sResult(_T(""));
115 | size_t bestLen = 0;
116 |
117 | do
118 | {
119 | CStdStringW sPath(lpwPath);
120 |
121 | vector drive(8);
122 | errno_t err = _wsplitpath_s(m_sTargetPath.c_str(), drive.data(), drive.size(), NULL, 0, NULL, 0, NULL, 0);
123 |
124 | if (err != 0)
125 | {
126 | break;
127 | }
128 |
129 | sPath = sPath.Right((int)sPath.length() - lstrlenW(&drive[0]));
130 |
131 | size_t idx = 0;
132 | std::vector::const_iterator iter;
133 | for (iter = vVfs.begin(); iter != vVfs.end(); iter++)
134 | {
135 | CVfsPath vfs = (CVfsPath)*iter;
136 | CStdStringW sSysPath(vfs.GetSystemPath());
137 |
138 | err = _wsplitpath_s(sSysPath.c_str(), drive.data(), drive.size(), NULL, 0, NULL, 0, NULL, 0);
139 | if (err != 0)
140 | {
141 | break;
142 | }
143 |
144 | sSysPath = sSysPath.Right((int)sSysPath.length() - lstrlenW(&drive[0]));
145 |
146 | if (!g_StringBegins_with(sPath, sSysPath))
147 | continue;
148 |
149 | size_t len = sSysPath.length();
150 | idx++;
151 |
152 | if (bestLen < len)
153 | {
154 | bestLen = len;
155 | CStdStringW sBuffer(sPath.Right((int)(sPath.length() - sSysPath.length())));
156 | sResult.Format(_T("VFS\\%s%s"), vfs.GetPath(), sBuffer);
157 | }
158 | }
159 |
160 | } while (FALSE);
161 |
162 | return sResult;
163 | }
--------------------------------------------------------------------------------
/IaUwpAppx/PackageFile.h:
--------------------------------------------------------------------------------
1 | // FILE: PackageFile.h
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #pragma once
29 |
30 | class CAssociation
31 | {
32 | public:
33 | CAssociation()
34 | {
35 | m_sId = _T("");
36 | m_sDescription = _T("");
37 | m_sIconfile = _T("");
38 | m_iconIdx = -1;
39 | m_sIconVFSpath = _T("");
40 | }
41 |
42 | ~CAssociation() {};
43 |
44 | const CAssociation& CAssociation::operator=(const CAssociation& association)
45 | {
46 | m_sId = association.m_sId;
47 | m_sDescription = association.m_sDescription;
48 | m_sIconfile = association.m_sIconfile;
49 | m_iconIdx = association.m_iconIdx;
50 | m_sIconVFSpath = association.m_sIconVFSpath;
51 |
52 | m_vExt.clear();
53 |
54 | std::vector::const_iterator iter;
55 | for (iter = association.m_vExt.begin(); iter != association.m_vExt.end(); iter++)
56 | {
57 | m_vExt.push_back((CStdStringW)*iter);
58 | }
59 |
60 | return *this;
61 | }
62 |
63 | /*
64 | friend bool operator== (const CAssociation &v1, const CAssociation &v2)
65 | {
66 | return (v1.m_sProgId == v2.m_sProgId &&
67 | v1.m_sDescription == v2.m_sDescription &&
68 | v1.m_sIconfile == v2.m_sIconfile &&
69 | v1.m_iconIdx == v2.m_iconIdx);
70 | }
71 |
72 | friend bool operator!= (const CAssociation &v1, const CAssociation &v2)
73 | {
74 | return !(v1 == v2);
75 | }*/
76 |
77 |
78 | // Shortcut data
79 | CStdStringW m_sId;
80 | CStdStringW m_sDescription;
81 | vector m_vExt;
82 | CStdStringW m_sIconfile;
83 | int m_iconIdx;
84 | CStdStringW m_sIconVFSpath;
85 | };
86 |
87 | class CShortcut
88 | {
89 | public:
90 | CShortcut()
91 | {
92 | m_sName = _T("");
93 | m_sDescription = _T("");
94 | m_sPath = _T("");
95 | m_sIconfile = _T("");
96 | m_sCmdline = _T("");
97 | m_iconIdx = -1;
98 | m_bEntryPoint = false;
99 | }
100 |
101 | ~CShortcut() {};
102 |
103 | const CShortcut& CShortcut::operator=(const CShortcut& shortcut)
104 | {
105 | m_sName = shortcut.m_sName;
106 | m_sDescription = shortcut.m_sDescription;
107 | m_sPath = shortcut.m_sPath;
108 | m_sCmdline = shortcut.m_sCmdline;
109 | m_sIconfile = shortcut.m_sIconfile;
110 | m_iconIdx = shortcut.m_iconIdx;
111 | m_bEntryPoint = shortcut.m_bEntryPoint;
112 | return *this;
113 | }
114 |
115 | friend bool operator== (const CShortcut &v1, const CShortcut &v2)
116 | {
117 | return (v1.m_sName == v2.m_sName &&
118 | v1.m_sDescription == v2.m_sDescription &&
119 | v1.m_sPath == v2.m_sPath &&
120 | v1.m_sCmdline == v2.m_sCmdline &&
121 | v1.m_sIconfile == v2.m_sIconfile &&
122 | v1.m_iconIdx == v2.m_iconIdx,
123 | v1.m_bEntryPoint == v2.m_bEntryPoint);
124 | }
125 |
126 | friend bool operator!= (const CShortcut &v1, const CShortcut &v2)
127 | {
128 | return !(v1 == v2);
129 | }
130 |
131 |
132 | // Shortcut data
133 | CStdStringW m_sName;
134 | CStdStringW m_sDescription;
135 | CStdStringW m_sPath;
136 | CStdStringW m_sCmdline;
137 | CStdStringW m_sIconfile;
138 | int m_iconIdx;
139 | bool m_bEntryPoint;
140 | };
141 |
142 | class CPackageFile
143 | {
144 | public:
145 | CPackageFile();
146 | ~CPackageFile();
147 |
148 | friend bool operator== (const CPackageFile &v1, const CPackageFile &v2);
149 | friend bool operator!= (const CPackageFile &v1, const CPackageFile &v2);
150 |
151 | UINT Set(LPCWSTR lpwSource, LPCWSTR lpwTarget, vector& vVfs);
152 | UINT Set(LPCWSTR lpwTarget, vector& vVfs);
153 |
154 | void Set(CAssociation& association)
155 | {
156 | m_association = association;
157 | }
158 |
159 | void Set(CShortcut& shortcut)
160 | {
161 | m_shortcut = shortcut;
162 | }
163 |
164 | LPCWSTR GetVFSpath() const
165 | {
166 | return m_sVFSpath.c_str();
167 | }
168 |
169 | LPCWSTR GetSourcePath() const
170 | {
171 | return m_sSourcePath.c_str();
172 | }
173 |
174 | CAssociation GetAssociation() const
175 | {
176 | return m_association;
177 | }
178 |
179 | CShortcut GetShortcut() const
180 | {
181 | return m_shortcut;
182 | }
183 |
184 | protected:
185 | CStdStringW m_sSourcePath;
186 | CStdStringW m_sTargetPath;
187 | CStdStringW m_sVFSpath;
188 |
189 | CAssociation m_association;
190 | CShortcut m_shortcut;
191 |
192 | protected:
193 | CStdStringW ResolveVFS(LPCWSTR lpwPath, vector& vVfs);
194 | };
195 |
--------------------------------------------------------------------------------
/IaUwpAppx/Resource.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/Resource.h
--------------------------------------------------------------------------------
/IaUwpAppx/VfsPath.cpp:
--------------------------------------------------------------------------------
1 | // FILE: VfsPath.cpp
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #include "stdafx.h"
29 | #include "VfsPath.h"
30 |
31 | bool operator== (const CVfsPath &v1, const CVfsPath &v2)
32 | {
33 | return (v1.m_sPath == v2.m_sPath &&
34 | v1.m_sSystemPath == v2.m_sSystemPath);
35 | }
36 |
37 | bool operator!= (CVfsPath &v1, CVfsPath &v2)
38 | {
39 | return !(v1 == v2);
40 | }
41 |
42 | CVfsPath::CVfsPath()
43 | {
44 | m_sPath = _T("");
45 | m_sSystemPath = _T("");
46 | }
47 |
48 | CVfsPath::~CVfsPath()
49 | {
50 | }
51 |
52 | bool CVfsPath::Set(LPCWSTR lpwPath, LPCWSTR lpwSystemPath)
53 | {
54 | if (!lpwPath || !lpwSystemPath)
55 | {
56 | return false;
57 | }
58 |
59 | m_sPath = lpwPath;
60 | m_sPath.Replace(L" ", L"%20");
61 | m_sSystemPath = lpwSystemPath;
62 |
63 | return true;
64 | }
--------------------------------------------------------------------------------
/IaUwpAppx/VfsPath.h:
--------------------------------------------------------------------------------
1 | // FILE: VfsPath.h
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #pragma once
29 |
30 | class CVfsPath
31 | {
32 | public:
33 | CVfsPath();
34 | ~CVfsPath();
35 |
36 | friend bool operator== (const CVfsPath &v1, const CVfsPath &v2);
37 | friend bool operator!= (const CVfsPath &v1, const CVfsPath &v2);
38 |
39 | bool Set(LPCWSTR lpwPath, LPCWSTR lpwSystemPath);
40 |
41 | CStdStringW GetPath() const
42 | {
43 | return m_sPath;
44 | }
45 |
46 | CStdStringW GetSystemPath() const
47 | {
48 | return m_sSystemPath;
49 | }
50 |
51 | protected:
52 | CStdStringW m_sPath;
53 | CStdStringW m_sSystemPath;
54 | };
55 |
--------------------------------------------------------------------------------
/IaUwpAppx/VirtualRegKey.cpp:
--------------------------------------------------------------------------------
1 | // FILE: VirtualRegKey.cpp
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #include "stdafx.h"
29 | #include "IaUwpAppxApp.h"
30 | #include "IaUwpAppx.h"
31 | #include "VirtualRegKey.h"
32 |
33 | bool operator== (const CVirtualRegKey &v1, const CVirtualRegKey &v2)
34 | {
35 | return (v1.m_hKeyRoot == v2.m_hKeyRoot &&
36 | v1.m_subKey == v2.m_subKey &&
37 | v1.m_dwType == v2.m_dwType &&
38 | v1.m_sValueName == v2.m_sValueName &&
39 | v1.m_binarySize == v2.m_binarySize &&
40 | v1.m_dwValue == v2.m_dwValue &&
41 | v1.m_sValue == v2.m_sValue &&
42 | v1.m_bWin32 == v2.m_bWin32 &&
43 | v1.m_unSupported == v2.m_unSupported);
44 | }
45 |
46 | bool operator!= (CVirtualRegKey &v1, CVirtualRegKey &v2)
47 | {
48 | return !(v1 == v2);
49 | }
50 |
51 | CVirtualRegKey::CVirtualRegKey()
52 | {
53 | m_hKeyRoot = 0;
54 | m_subKey = _T("");
55 | m_dwType = 0;
56 | m_sValueName = _T("");
57 | m_pBinaryValue = NULL;
58 | m_binarySize = 0;
59 | m_dwValue = 0 ;
60 | m_sValue = _T("");
61 | m_bWin32 = false;
62 | m_unSupported = false;
63 | }
64 |
65 | CVirtualRegKey::~CVirtualRegKey()
66 | {
67 |
68 | }
69 |
70 | UINT CVirtualRegKey::Set(HKEY hKey, LPCWSTR lpSubKey, DWORD dwType, LPCWSTR lpValueName, LPVOID lpValue, DWORD dwSize, bool bWin32)
71 | {
72 | UINT result = UAPPX_SUCCESS;
73 |
74 | if (!lpSubKey || dwType == 0 || !lpValueName || !lpValue)
75 | {
76 | return UAPPX_PARAM_ERROR;
77 | }
78 |
79 | if (m_dwType == REG_BINARY && dwSize == 0)
80 | {
81 | return UAPPX_PARAM_ERROR;
82 | }
83 |
84 | m_hKeyRoot = hKey;
85 | m_subKey = lpSubKey;
86 | m_dwType = dwType;
87 | m_sValueName = lpValueName;
88 | m_bWin32 = bWin32;
89 |
90 | if(hKey == HKEY_CURRENT_USER || hKey == HKEY_CURRENT_CONFIG)
91 | {
92 | m_subKey.Format(_T("REGISTRY\\USER\\%s"), m_subKey);
93 | }
94 | else if (hKey == HKEY_LOCAL_MACHINE || HKEY_CLASSES_ROOT)
95 | {
96 | m_subKey.Format(_T("REGISTRY\\MACHINE\\%s"), m_subKey);
97 | }
98 | else
99 | {
100 | // Not handled!
101 | m_unSupported = true;
102 | }
103 |
104 | switch (m_dwType)
105 | {
106 | case REG_BINARY:
107 | m_pBinaryValue = new BYTE [dwSize];
108 |
109 | if (m_pBinaryValue)
110 | {
111 | errno_t err = memcpy_s(m_pBinaryValue, dwSize, lpValue, dwSize);
112 |
113 | if (err)
114 | {
115 | delete[] m_pBinaryValue;
116 | m_pBinaryValue = NULL;
117 |
118 | result = UAPPX_OUT_OF_MEMORY_ERROR;
119 | }
120 | else
121 | {
122 | m_binarySize = dwSize;
123 | }
124 | }
125 | else
126 | {
127 | result = UAPPX_OUT_OF_MEMORY_ERROR;
128 | }
129 | break;
130 |
131 | case REG_DWORD:
132 | m_dwValue = *(LPDWORD)lpValue;
133 | break;
134 |
135 | case REG_QWORD:
136 | // Not handled!
137 | result = UAPPX_UNSUPPORTED_REGISTRY_VALUE;
138 | break;
139 |
140 | case REG_SZ:
141 | case REG_EXPAND_SZ:
142 | case REG_LINK:
143 | case REG_MULTI_SZ:
144 | m_sValue = (LPCWSTR)lpValue;
145 | break;
146 |
147 | default:
148 | result = UAPPX_UNSUPPORTED_REGISTRY_VALUE;
149 | break;
150 | }
151 |
152 | return result;
153 | }
154 |
155 | LPVOID CVirtualRegKey::GetValue(DWORD& dwType)
156 | {
157 | LPVOID lpValue = NULL;
158 |
159 | dwType = m_dwType;
160 |
161 | switch (m_dwType)
162 | {
163 | case REG_BINARY:
164 | lpValue = (LPVOID)&m_pBinaryValue;
165 | break;
166 |
167 | case REG_DWORD:
168 | lpValue = (LPVOID)&m_dwValue;
169 | break;
170 |
171 | //case REG_QWORD:
172 | // // Not handled!
173 | // result = false;
174 | // break;
175 |
176 | case REG_SZ:
177 | case REG_EXPAND_SZ:
178 | case REG_LINK:
179 | case REG_MULTI_SZ:
180 | lpValue = (LPVOID)&m_sValue;
181 | break;
182 |
183 | default:
184 | break;
185 | }
186 |
187 | return lpValue;
188 | }
--------------------------------------------------------------------------------
/IaUwpAppx/VirtualRegKey.h:
--------------------------------------------------------------------------------
1 | // FILE: VirtualRegKey.h
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #pragma once
29 |
30 | class CVirtualRegKey
31 | {
32 | public:
33 | CVirtualRegKey();
34 |
35 | ~CVirtualRegKey();
36 |
37 | void Clear()
38 | {
39 | if (m_pBinaryValue)
40 | {
41 | delete[] m_pBinaryValue;
42 | m_pBinaryValue = NULL;
43 |
44 | m_binarySize = 0;
45 | }
46 |
47 | m_hKeyRoot = 0;
48 | m_subKey = _T("");
49 | m_dwType = 0;
50 | m_sValueName = _T("");
51 | m_binarySize = 0;
52 | m_dwValue = 0;
53 | m_sValue = _T("");
54 | m_bWin32 = false;
55 | m_unSupported = false;
56 | }
57 |
58 | friend bool operator== (const CVirtualRegKey &v1, const CVirtualRegKey &v2);
59 | friend bool operator!= (const CVirtualRegKey &v1, const CVirtualRegKey &v2);
60 |
61 | UINT Set(HKEY hKey, LPCWSTR lpSubKey, DWORD dwType, LPCWSTR lpValueName, LPVOID lpValue, DWORD dwSize, bool bWin32);
62 |
63 | bool IsUnSupported()
64 | {
65 | return m_unSupported;
66 | }
67 |
68 | CStdStringW GetSubKey()
69 | {
70 | return m_subKey;
71 | }
72 |
73 | CStdStringW GetValueName()
74 | {
75 | return m_sValueName;
76 | }
77 |
78 | LPVOID GetValue(DWORD& dwType);
79 | DWORD GetBinaryValueSize() const
80 | {
81 | return m_binarySize;
82 | }
83 |
84 | protected:
85 | HKEY m_hKeyRoot;
86 | CStdStringW m_subKey;
87 | DWORD m_dwType;
88 | CStdStringW m_sValueName;
89 | LPBYTE m_pBinaryValue;
90 | DWORD m_binarySize;
91 | DWORD m_dwValue;
92 | CStdStringW m_sValue;
93 | bool m_bWin32;
94 |
95 | bool m_unSupported;
96 | };
--------------------------------------------------------------------------------
/IaUwpAppx/bin x64/IaUwpAppx64.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/bin x64/IaUwpAppx64.dll
--------------------------------------------------------------------------------
/IaUwpAppx/bin x64/IaUwpAppx64.exp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/bin x64/IaUwpAppx64.exp
--------------------------------------------------------------------------------
/IaUwpAppx/bin x64/IaUwpAppx64.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/bin x64/IaUwpAppx64.lib
--------------------------------------------------------------------------------
/IaUwpAppx/bin x86/IaUwpAppx.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/bin x86/IaUwpAppx.dll
--------------------------------------------------------------------------------
/IaUwpAppx/bin x86/IaUwpAppx.exp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/bin x86/IaUwpAppx.exp
--------------------------------------------------------------------------------
/IaUwpAppx/bin x86/IaUwpAppx.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/bin x86/IaUwpAppx.lib
--------------------------------------------------------------------------------
/IaUwpAppx/embedded_res/150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/embedded_res/150x150.png
--------------------------------------------------------------------------------
/IaUwpAppx/embedded_res/44x44.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/embedded_res/44x44.png
--------------------------------------------------------------------------------
/IaUwpAppx/embedded_res/AppxManifest_schema.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $$$
6 | $$$
7 | $$$
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | $$$
20 |
21 |
--------------------------------------------------------------------------------
/IaUwpAppx/embedded_res/PackageLogo.50x50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/embedded_res/PackageLogo.50x50.png
--------------------------------------------------------------------------------
/IaUwpAppx/embedded_res/main.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/embedded_res/main.ico
--------------------------------------------------------------------------------
/IaUwpAppx/libs/DFRegistry.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/libs/DFRegistry.lib
--------------------------------------------------------------------------------
/IaUwpAppx/libs/DFRegistry64.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/libs/DFRegistry64.lib
--------------------------------------------------------------------------------
/IaUwpAppx/libs/DFRegistry_exp.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/libs/DFRegistry_exp.h
--------------------------------------------------------------------------------
/IaUwpAppx/libs/dffileop.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/libs/dffileop.lib
--------------------------------------------------------------------------------
/IaUwpAppx/libs/dffileop64.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/libs/dffileop64.lib
--------------------------------------------------------------------------------
/IaUwpAppx/libs/dffileop_exp.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/libs/dffileop_exp.h
--------------------------------------------------------------------------------
/IaUwpAppx/libs/stdstring.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/libs/stdstring.h
--------------------------------------------------------------------------------
/IaUwpAppx/res/IaUwpAppx.rc2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/installaware/APPX/9560b6ae3f6d7f8c91298f8993d82771ed1321f4/IaUwpAppx/res/IaUwpAppx.rc2
--------------------------------------------------------------------------------
/IaUwpAppx/stdafx.cpp:
--------------------------------------------------------------------------------
1 | // stdafx.cpp : source file that includes just the standard includes
2 | // IaUwpAppx.pch will be the pre-compiled header
3 | // stdafx.obj will contain the pre-compiled type information
4 |
5 | // InstallAware APPX Library for Microsoft's Desktop Bridge
6 | // Copyright(C) 2016 InstallAware Software
7 | //
8 | // This program is free software : you can redistribute it and / or modify
9 | // it under the terms of the GNU Affero General Public License as published
10 | // by the Free Software Foundation, either version 3 of the License, or
11 | // (at your option) any later version.
12 | //
13 | // This program is distributed in the hope that it will be useful,
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
16 | // GNU Affero General Public License for more details.
17 | //
18 | // You should have received a copy of the GNU Affero General Public License
19 | // along with this program.If not, see .
20 | //
21 | // Contact InstallAware Software at support@installaware.com.
22 |
23 | // REVISION HISTORY
24 | //
25 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
26 | //
27 | //
28 | //
29 |
30 | #include "stdafx.h"
31 |
32 |
33 |
--------------------------------------------------------------------------------
/IaUwpAppx/stdafx.h:
--------------------------------------------------------------------------------
1 | // stdafx.h : include file for standard system include files,
2 | // or project specific include files that are used frequently, but
3 | // are changed infrequently
4 |
5 | // InstallAware APPX Library for Microsoft's Desktop Bridge
6 | // Copyright(C) 2016 InstallAware Software
7 | //
8 | // This program is free software : you can redistribute it and / or modify
9 | // it under the terms of the GNU Affero General Public License as published
10 | // by the Free Software Foundation, either version 3 of the License, or
11 | // (at your option) any later version.
12 | //
13 | // This program is distributed in the hope that it will be useful,
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
16 | // GNU Affero General Public License for more details.
17 | //
18 | // You should have received a copy of the GNU Affero General Public License
19 | // along with this program.If not, see .
20 | //
21 | // Contact InstallAware Software at support@installaware.com.
22 |
23 | // REVISION HISTORY
24 | //
25 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
26 | //
27 | //
28 | //
29 |
30 | #pragma once
31 |
32 | #ifndef VC_EXTRALEAN
33 | #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
34 | #endif
35 |
36 | #include "targetver.h"
37 |
38 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
39 |
40 | #include // MFC core and standard components
41 | #include // MFC extensions
42 |
43 | #ifndef _AFX_NO_OLE_SUPPORT
44 | #include // MFC OLE classes
45 | #include // MFC OLE dialog classes
46 | #include // MFC Automation classes
47 | #endif // _AFX_NO_OLE_SUPPORT
48 |
49 | #ifndef _AFX_NO_DB_SUPPORT
50 | #include // MFC ODBC database classes
51 | #endif // _AFX_NO_DB_SUPPORT
52 |
53 | #ifndef _AFX_NO_DAO_SUPPORT
54 | #include // MFC DAO database classes
55 | #endif // _AFX_NO_DAO_SUPPORT
56 |
57 | #ifndef _AFX_NO_OLE_SUPPORT
58 | #include // MFC support for Internet Explorer 4 Common Controls
59 | #endif
60 | #ifndef _AFX_NO_AFXCMN_SUPPORT
61 | #include // MFC support for Windows Common Controls
62 | #endif // _AFX_NO_AFXCMN_SUPPORT
63 |
64 | #if (!defined STDSTRING_H)
65 | #include
66 | #endif
67 |
68 | #include
69 | #include
70 |
71 | #include
72 | #include
73 | #include
74 | #include
75 | #include
76 | using namespace std;
77 |
78 | #include "utils.h"
79 |
80 |
--------------------------------------------------------------------------------
/IaUwpAppx/targetver.h:
--------------------------------------------------------------------------------
1 | // FILE: targetver.h
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #pragma once
29 |
30 | // Including SDKDDKVer.h defines the highest available Windows platform.
31 |
32 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
33 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
34 |
35 | #define _WIN32_WINNT _WIN32_WINNT_WINBLUE
36 | #define WINVER _WIN32_WINNT_WINBLUE
37 |
38 | #include
39 |
--------------------------------------------------------------------------------
/IaUwpAppx/utils.h:
--------------------------------------------------------------------------------
1 | // FILE: utils.h
2 | //
3 | // InstallAware APPX Library for Microsoft's Desktop Bridge
4 | // Copyright(C) 2016 InstallAware Software
5 | //
6 | // This program is free software : you can redistribute it and / or modify
7 | // it under the terms of the GNU Affero General Public License as published
8 | // by the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 | // GNU Affero General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU Affero General Public License
17 | // along with this program.If not, see .
18 | //
19 | // Contact InstallAware Software at support@installaware.com.
20 |
21 | // REVISION HISTORY
22 | //
23 | // 2016-DEC-08 - Version 1.0.2.301 - First Open Source release.
24 | //
25 | //
26 | //
27 |
28 | #pragma once
29 |
30 | #include "VfsPath.h"
31 | #include
32 |
33 | static CStdStringW g_GetGuId()
34 | {
35 | CStdStringW sResult(_T(""));
36 | RPC_WSTR guidStr = NULL;
37 |
38 | GUID guid;
39 | HRESULT hr = CoCreateGuid(&guid);
40 | // Convert the GUID to a string
41 | UuidToStringW(&guid, &guidStr);
42 |
43 | sResult.Format(_T("%s"), guidStr);
44 | RpcStringFreeW(&guidStr);
45 |
46 | return sResult;
47 | }
48 |
49 | static CStdStringW g_GetTempDirectory()
50 | {
51 | CStdStringW result = _T("");
52 |
53 | wchar_t wcharPath[MAX_PATH];
54 | if (::GetTempPathW(MAX_PATH, wcharPath))
55 | result = wcharPath;
56 |
57 | return result;
58 | }
59 |
60 | static bool g_StringBegins_with(CStdString input, CStdString match)
61 | {
62 | input = input.ToLower();
63 | match = match.ToLower();
64 |
65 | return input.size() >= match.size()
66 | && equal(match.begin(), match.end(), input.begin());
67 | }
68 |
69 | static void g_StdStrSplit(CStdString str, WCHAR ch, std::vector& results)
70 | {
71 | size_t cutAt;
72 | while ((cutAt = str.find_first_of(ch)) != str.npos)
73 | {
74 | if (cutAt > 0)
75 | {
76 | results.push_back(str.substr(0, cutAt));
77 | }
78 | str = str.substr(cutAt + 1);
79 | }
80 |
81 | if (str.length() > 0)
82 | {
83 | results.push_back(str);
84 | }
85 | }
86 |
87 | template
88 | static void g_VectorRemoveElement(std::vector& vec, size_t pos)
89 | {
90 | std::vector::iterator it = vec.begin();
91 | std::advance(it, pos);
92 | vec.erase(it);
93 | }
94 |
95 | static BOOL g_SetRegKeyPermission(LPCTSTR lpszKey)
96 | {
97 | BOOL result = TRUE;
98 |
99 | DWORD dwRes = 0;
100 | DWORD dwDisposition = 0;
101 | PSID pEveryoneSID = NULL, pAdminSID = NULL;
102 | PACL pACL = NULL;
103 | PSECURITY_DESCRIPTOR pSD = NULL;
104 | EXPLICIT_ACCESS ea[2];
105 | SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
106 | SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
107 | SECURITY_ATTRIBUTES sa;
108 | HKEY hkSub = NULL;
109 |
110 | // Create a well-known SID for the Everyone group.
111 | if (!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID))
112 | {
113 | result = FALSE;
114 | goto Cleanup;
115 | }
116 |
117 | // Initialize an EXPLICIT_ACCESS structure for an ACE.
118 | // The ACE will allow Everyone read access to the key.
119 | ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
120 | ea[0].grfAccessPermissions = KEY_READ;
121 | ea[0].grfAccessMode = SET_ACCESS;
122 | ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
123 | ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
124 | ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
125 | ea[0].Trustee.ptstrName = (LPTSTR)pEveryoneSID;
126 |
127 | // Create a SID for the BUILTIN\Administrators group.
128 | if (!AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSID))
129 | {
130 | result = FALSE;
131 | goto Cleanup;
132 | }
133 |
134 | // Initialize an EXPLICIT_ACCESS structure for an ACE.
135 | // The ACE will allow the Administrators group full access to
136 | // the key.
137 | ea[1].grfAccessPermissions = KEY_ALL_ACCESS;
138 | ea[1].grfAccessMode = SET_ACCESS;
139 | ea[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
140 | ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
141 | ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
142 | ea[1].Trustee.ptstrName = (LPTSTR)pAdminSID;
143 |
144 | // Create a new ACL that contains the new ACEs.
145 | dwRes = SetEntriesInAcl(2, ea, NULL, &pACL);
146 | if (ERROR_SUCCESS != dwRes)
147 | {
148 | result = FALSE;
149 | goto Cleanup;
150 | }
151 |
152 | // Initialize a security descriptor.
153 | pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
154 | if (NULL == pSD)
155 | {
156 | result = FALSE;
157 | goto Cleanup;
158 | }
159 |
160 | if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
161 | {
162 | result = FALSE;
163 | goto Cleanup;
164 | }
165 |
166 | // Add the ACL to the security descriptor.
167 | if (!SetSecurityDescriptorDacl(pSD,
168 | TRUE, // bDaclPresent flag
169 | pACL,
170 | FALSE)) // not a default DACL
171 | {
172 | result = FALSE;
173 | goto Cleanup;
174 | }
175 |
176 | // Initialize a security attributes structure.
177 | sa.nLength = sizeof(SECURITY_ATTRIBUTES);
178 | sa.lpSecurityDescriptor = pSD;
179 | sa.bInheritHandle = FALSE;
180 |
181 | // Use the security attributes to set the security descriptor
182 | // when you create a key.
183 | LONG lRes = RegCreateKeyEx(HKEY_CURRENT_USER, lpszKey, 0, _T(""), 0, KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
184 |
185 | if(lRes == ERROR_SUCCESS)
186 | {
187 | result = TRUE;
188 | }
189 |
190 | Cleanup:
191 |
192 | if (pEveryoneSID)
193 | FreeSid(pEveryoneSID);
194 | if (pAdminSID)
195 | FreeSid(pAdminSID);
196 | if (pACL)
197 | LocalFree(pACL);
198 | if (pSD)
199 | LocalFree(pSD);
200 | if (hkSub)
201 | RegCloseKey(hkSub);
202 |
203 | return result;
204 | }
205 |
206 | static bool g_ExtractModuleResource(UINT uResourceID, LPCWSTR lpType, LPCWSTR lpDestination)
207 | {
208 | bool result = false;
209 |
210 | if (!lpDestination || !lpType)
211 | return result;
212 |
213 | HANDLE hFile = INVALID_HANDLE_VALUE;
214 | DWORD dwResourceSize = 0;
215 | LPVOID lpResource = NULL;
216 |
217 | do
218 | {
219 |
220 | #if (defined _WIN64)
221 | HMODULE hModule = ::GetModuleHandle(_T("IaUwpAppx64.dll"));
222 | #else
223 | HMODULE hModule = ::GetModuleHandle(_T("IaUwpAppx.dll"));
224 | #endif
225 |
226 | if (!hModule)
227 | break;
228 |
229 | // Find the binary file in resources
230 | HRSRC hRsrc = ::FindResource(hModule, MAKEINTRESOURCE(uResourceID), lpType);
231 |
232 | if (!hRsrc)
233 | break;
234 |
235 | HGLOBAL hResource = ::LoadResource(hModule, hRsrc);
236 | if (!hResource)
237 | break;
238 |
239 | lpResource = ::LockResource(hResource);
240 |
241 | if (lpResource)
242 | {
243 | dwResourceSize = ::SizeofResource(hModule, hRsrc);
244 | }
245 |
246 | if (!lpResource)
247 | break;
248 |
249 | // Copy extracted binary from resources to destination
250 | hFile = ::CreateFile(lpDestination, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
251 |
252 | if (hFile == INVALID_HANDLE_VALUE)
253 | return result;
254 |
255 | result = (::WriteFile(hFile, lpResource, dwResourceSize, NULL, NULL) != 0);
256 | DWORD dwError = GetLastError();
257 |
258 | } while (FALSE);
259 |
260 |
261 | if (hFile != INVALID_HANDLE_VALUE)
262 | CloseHandle(hFile);
263 |
264 | return result;
265 | }
266 |
267 | static DWORD g_StartProcess(LPWSTR szCmdLine)
268 | {
269 | DWORD result = 0;
270 | STARTUPINFO si;
271 | PROCESS_INFORMATION pi;
272 |
273 | ZeroMemory(&si, sizeof(si));
274 | si.cb = sizeof(si);
275 | ZeroMemory(&pi, sizeof(pi));
276 |
277 | si.dwFlags = STARTF_USESHOWWINDOW;
278 | si.wShowWindow = SW_HIDE;
279 |
280 | // Start the child process.
281 | if (!CreateProcess(NULL, // No module name (use command line)
282 | szCmdLine, // Command line
283 | NULL, // Process handle not inheritable
284 | NULL, // Thread handle not inheritable
285 | FALSE, // Set handle inheritance to FALSE
286 | CREATE_NO_WINDOW, // No creation flags
287 | NULL, // Use parent's environment block
288 | NULL, // Use parent's starting directory
289 | &si, // Pointer to STARTUPINFO structure
290 | &pi) // Pointer to PROCESS_INFORMATION structure
291 | )
292 | {
293 | result = GetLastError();
294 | return result;
295 | }
296 |
297 | // Wait until child process exits.
298 | DWORD dwExitCode = -1;
299 | DWORD dwWaitResult = WaitForSingleObject(pi.hProcess, INFINITE);
300 |
301 | if (dwWaitResult == WAIT_OBJECT_0)
302 | {
303 | GetExitCodeProcess(pi.hProcess, &dwExitCode);
304 | result = dwExitCode;
305 | }
306 | else
307 | {
308 | result = GetLastError();
309 | //failure
310 | }
311 |
312 | // Close process and thread handles.
313 | if (pi.hProcess)
314 | CloseHandle(pi.hProcess);
315 | if (pi.hThread)
316 | CloseHandle(pi.hThread);
317 |
318 | return result;
319 | }
320 |
321 | static DWORD g_GetCertificateSubject(LPCWSTR pwPfxFile, LPCWSTR pwPfxPassword, LPWSTR& pwSubject)
322 | {
323 | if ((!pwPfxFile || !pwPfxPassword) && pwSubject)
324 | return ERROR_INVALID_PARAMETER;
325 |
326 | DWORD result = ERROR_SUCCESS;
327 |
328 | HANDLE hCertFile = INVALID_HANDLE_VALUE;
329 | CRYPT_DATA_BLOB pfxBlob = { 0 };
330 | HCERTSTORE hPfxStore = NULL;
331 | PCCERT_CONTEXT pcCert = NULL;
332 |
333 | do
334 | {
335 | hCertFile = CreateFile(pwPfxFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
336 |
337 | if (hCertFile == INVALID_HANDLE_VALUE)
338 | {
339 | result = GetLastError();
340 | break;
341 | }
342 |
343 | DWORD dwFileSize = GetFileSize(hCertFile, NULL);
344 |
345 | CRYPT_DATA_BLOB pfxBlob;
346 | pfxBlob.pbData = (PBYTE)CryptMemAlloc(dwFileSize * sizeof(BYTE));
347 |
348 | if (!pfxBlob.pbData)
349 | {
350 | result = ERROR_INVALID_HANDLE;
351 | break;
352 | }
353 |
354 | pfxBlob.cbData = dwFileSize;
355 |
356 | DWORD cbRead = NULL;
357 | ReadFile(hCertFile, pfxBlob.pbData, pfxBlob.cbData, &cbRead, NULL);
358 |
359 | CloseHandle(hCertFile);
360 | hCertFile = INVALID_HANDLE_VALUE;
361 |
362 | hPfxStore = PFXImportCertStore(&pfxBlob, pwPfxPassword, CRYPT_EXPORTABLE | CRYPT_USER_KEYSET);
363 | if (!hPfxStore)
364 | {
365 | result = GetLastError();
366 | break;
367 | }
368 |
369 | CryptMemFree(pfxBlob.pbData);
370 | pfxBlob.pbData = NULL;
371 |
372 | pcCert = CertFindCertificateInStore(hPfxStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL);
373 |
374 | if (!pcCert)
375 | {
376 | result = GetLastError();
377 | break;
378 | }
379 |
380 | // subject
381 | DWORD cbSize = CertNameToStr(X509_ASN_ENCODING, &pcCert->pCertInfo->Subject, CERT_X500_NAME_STR, NULL, 0);
382 |
383 | if (cbSize <= 1)
384 | {
385 | result = ERROR_INVALID_DATA;
386 | break;
387 | }
388 |
389 | pwSubject = new wchar_t[cbSize];
390 |
391 | if (!pwSubject)
392 | {
393 | result = ERROR_OUTOFMEMORY;
394 | break;
395 | }
396 |
397 | if (!CertNameToStr(X509_ASN_ENCODING, &pcCert->pCertInfo->Subject, CERT_X500_NAME_STR, pwSubject, cbSize))
398 | {
399 | delete[] pwSubject;
400 | pwSubject = NULL;
401 | }
402 |
403 | } while (FALSE);
404 |
405 | if (hCertFile != INVALID_HANDLE_VALUE)
406 | {
407 | CloseHandle(hCertFile);
408 | }
409 |
410 | if (pfxBlob.pbData)
411 | {
412 | CryptMemFree(pfxBlob.pbData);
413 | }
414 |
415 | if (pcCert)
416 | {
417 | CertFreeCertificateContext(pcCert);
418 | }
419 |
420 | if (hPfxStore)
421 | {
422 | if (!CertCloseStore(hPfxStore, CERT_CLOSE_STORE_FORCE_FLAG))
423 | {
424 | DWORD dw = GetLastError();
425 | }
426 | }
427 |
428 | return result;
429 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # APPX
2 | InstallAware© APPX Library for Microsoft's Desktop Bridge
3 |
4 | InstallAware is the only vendor giving developers a free ride across Microsoft’s Desktop Bridge to the Universal Windows Platform highway. Use InstallAware's free and open source APPX Builder Library, together with the free and open source single-step command line converter, to compile any pre-existing Win32, Win64, or .NET application as a modern Universal Windows Platform app. The source code for the DLL and the quick command line converter are both published under the GNU AGPLv3, helping any open source installer such as Inno and NSIS, and partially open source installer such as Windows Installer XML (WiX lacks open source or free APPX support), bridge the setups they create to the Universal Windows Platform via Microsoft®’s Desktop Bridge.
5 |
6 | Requirements;
7 | - Microsoft Visual Studio 2015
8 | - Windows 10 SDK
9 |
10 | https://www.installaware.com/
11 |
--------------------------------------------------------------------------------
/Samples/Quick Command Line Tool manual.txt:
--------------------------------------------------------------------------------
1 | Quick Command Line Tool for Creating APPX Applications
2 |
3 | Purpose: This tool is based on the open source InstallAware APPX Library, wrapping the library inside a quick command line interface which converts traditional Win32/Win64/.NET apps to modern Universal Windows Platform APPX binaries, ready for submission to the Windows Store, and without requiring Visual Studio 2017.
4 |
5 | Requirements: This tool requires the Windows 10 SDK, as it consumes the MAKEAPPX and SIGNTOOL binaries included in the SDK. This tool also requires the open source InstallAware APPX Library itself, IaUwpAppx.dll, as well as its dependency libraries dffileop.dll and dfregistry.dll. These dependencies and binaries are provided in the "bin x86" and "bin x64" subfolders of the "samples" folder, for 32-bit and 64-bit platforms respectively.
6 |
7 | Usage:
8 |
9 | IaAppxBuilder.exe /s /o