VirtualBox

source: vbox/trunk/src/VBox/Main/testcase/tstUnattendedScript.cpp@ 101683

Last change on this file since 101683 was 101683, checked in by vboxsync, 13 months ago

Main/Unattended|GuestOSType: Add an entry in the guest OS type to indicate the name of the additions install package instead of hardcoding it in the templates. Allows easy adaption if something changes and makes it possible to auto install guest additions for linux.arm64 guests, bugref:10542

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.4 KB
Line 
1/* $Id: tstUnattendedScript.cpp 101683 2023-10-31 12:38:46Z vboxsync $ */
2/** @file
3 * tstUnattendedScript - testcases for UnattendedScript.
4 */
5
6/*
7 * Copyright (C) 2022-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#include "UnattendedScript.h"
33
34#include <VBox/com/VirtualBox.h>
35#include <VBox/com/errorprint.h>
36
37#include <iprt/file.h>
38#include <iprt/path.h>
39#include <iprt/test.h>
40#include <iprt/stream.h>
41
42#include "VirtualBoxBase.h"
43#include "UnattendedImpl.h"
44#include "UnattendedScript.h"
45#include "VirtualBoxImpl.h"
46#include "MachineImpl.h"
47
48using namespace std;
49
50
51/*********************************************************************************************************************************
52* Unattended Stub Implementation *
53*********************************************************************************************************************************/
54Unattended::Unattended()
55 : mhThreadReconfigureVM(NIL_RTNATIVETHREAD), mfRtcUseUtc(false), mfGuestOs64Bit(false)
56 , mpInstaller(NULL), mpTimeZoneInfo(NULL), mfIsDefaultAuxiliaryBasePath(true), mfDoneDetectIsoOS(false)
57{
58 mStrUser = "vboxuser";
59 mStrPassword = "changeme";
60 mStrFullUserName = "VBox & VBox;";
61 mStrProductKey = "911";
62 mStrIsoPath = "/iso/path/file.iso";
63 mStrAdditionsIsoPath = "/iso/path/addition.iso";
64 mfInstallGuestAdditions = true;
65 mfInstallTestExecService = true;
66 mStrValidationKitIsoPath = "/iso/path/valkit.iso";
67 mStrTimeZone = "cet";
68 mpTimeZoneInfo = NULL;
69 mStrLocale = "dk_DK";
70 mStrLanguage = "dk";
71 mStrCountry = "DK";
72 //mPackageSelectionAdjustments = "minimal";
73 mStrHostname = "my-extra-long-name.hostname.com";
74 mStrAuxiliaryBasePath = "/aux/path/pfx-";
75 mfIsDefaultAuxiliaryBasePath = false;
76 midxImage = 42;
77 mStrScriptTemplatePath = "/path/to/script-template.file";
78 mStrPostInstallScriptTemplatePath = "/path/to/post-install-template.file";
79 mStrPostInstallCommand = "/bin/post-install-command arg1 arg2 --amp=& --lt=< --gt=> --dq-word=\"word\" --sq-word='word'";
80 mStrExtraInstallKernelParameters = "extra=kernel parameters quiet amp=& lt=< gt=>";
81 mStrProxy = "http://proxy.intranet.com:443";
82
83 mfDoneDetectIsoOS = true;
84 mStrDetectedOSTypeId = "MyOSTypeId";
85 mStrDetectedOSVersion = "3.4.2";
86 mStrDetectedOSFlavor = "server";
87 //mDetectedOSLanguages = "en_UK"
88 mStrDetectedOSHints = "nudge nudge wink wink";
89 mStrAdditionsInstallPackage = "Something-none-existing.run";
90}
91
92Unattended::~Unattended()
93{
94}
95
96HRESULT Unattended::FinalConstruct()
97{
98 return BaseFinalConstruct();
99}
100
101void Unattended::FinalRelease()
102{
103 uninit();
104 BaseFinalRelease();
105}
106
107void Unattended::uninit()
108{
109}
110
111HRESULT Unattended::initUnattended(VirtualBox *aParent)
112{
113 unconst(mParent) = aParent;
114 return S_OK;
115}
116
117HRESULT Unattended::detectIsoOS()
118{
119 return E_NOTIMPL;
120}
121
122
123HRESULT Unattended::prepare()
124{
125 return E_NOTIMPL;
126}
127
128HRESULT Unattended::constructMedia()
129{
130 return E_NOTIMPL;
131}
132
133HRESULT Unattended::reconfigureVM()
134{
135 return E_NOTIMPL;
136}
137
138HRESULT Unattended::done()
139{
140 return E_NOTIMPL;
141}
142
143HRESULT Unattended::getIsoPath(com::Utf8Str &isoPath)
144{
145 RT_NOREF(isoPath);
146 return E_NOTIMPL;
147}
148
149HRESULT Unattended::setIsoPath(const com::Utf8Str &isoPath)
150{
151 RT_NOREF(isoPath);
152 return E_NOTIMPL;
153}
154
155HRESULT Unattended::getUser(com::Utf8Str &user)
156{
157 RT_NOREF(user);
158 return E_NOTIMPL;
159}
160
161
162HRESULT Unattended::setUser(const com::Utf8Str &user)
163{
164 RT_NOREF(user);
165 return E_NOTIMPL;
166}
167
168HRESULT Unattended::getPassword(com::Utf8Str &password)
169{
170 RT_NOREF(password);
171 return E_NOTIMPL;
172}
173
174HRESULT Unattended::setPassword(const com::Utf8Str &password)
175{
176 RT_NOREF(password);
177 return E_NOTIMPL;
178}
179
180HRESULT Unattended::getFullUserName(com::Utf8Str &fullUserName)
181{
182 RT_NOREF(fullUserName);
183 return E_NOTIMPL;
184}
185
186HRESULT Unattended::setFullUserName(const com::Utf8Str &fullUserName)
187{
188 RT_NOREF(fullUserName);
189 return E_NOTIMPL;
190}
191
192HRESULT Unattended::getProductKey(com::Utf8Str &productKey)
193{
194 RT_NOREF(productKey);
195 return E_NOTIMPL;
196}
197
198HRESULT Unattended::setProductKey(const com::Utf8Str &productKey)
199{
200 RT_NOREF(productKey);
201 return E_NOTIMPL;
202}
203
204HRESULT Unattended::getAdditionsIsoPath(com::Utf8Str &additionsIsoPath)
205{
206 RT_NOREF(additionsIsoPath);
207 return E_NOTIMPL;
208}
209
210HRESULT Unattended::setAdditionsIsoPath(const com::Utf8Str &additionsIsoPath)
211{
212 RT_NOREF(additionsIsoPath);
213 return E_NOTIMPL;
214}
215
216HRESULT Unattended::getInstallGuestAdditions(BOOL *installGuestAdditions)
217{
218 RT_NOREF(installGuestAdditions);
219 return E_NOTIMPL;
220}
221
222HRESULT Unattended::setInstallGuestAdditions(BOOL installGuestAdditions)
223{
224 RT_NOREF(installGuestAdditions);
225 return E_NOTIMPL;
226}
227
228HRESULT Unattended::getValidationKitIsoPath(com::Utf8Str &aValidationKitIsoPath)
229{
230 RT_NOREF(aValidationKitIsoPath);
231 return E_NOTIMPL;
232}
233
234HRESULT Unattended::setValidationKitIsoPath(const com::Utf8Str &aValidationKitIsoPath)
235{
236 RT_NOREF(aValidationKitIsoPath);
237 return E_NOTIMPL;
238}
239
240HRESULT Unattended::getInstallTestExecService(BOOL *aInstallTestExecService)
241{
242 RT_NOREF(aInstallTestExecService);
243 return E_NOTIMPL;
244}
245
246HRESULT Unattended::setInstallTestExecService(BOOL aInstallTestExecService)
247{
248 RT_NOREF(aInstallTestExecService);
249 return E_NOTIMPL;
250}
251
252HRESULT Unattended::getTimeZone(com::Utf8Str &aTimeZone)
253{
254 RT_NOREF(aTimeZone);
255 return E_NOTIMPL;
256}
257
258HRESULT Unattended::setTimeZone(const com::Utf8Str &aTimezone)
259{
260 RT_NOREF(aTimezone);
261 return E_NOTIMPL;
262}
263
264HRESULT Unattended::getLocale(com::Utf8Str &aLocale)
265{
266 RT_NOREF(aLocale);
267 return E_NOTIMPL;
268}
269
270HRESULT Unattended::setLocale(const com::Utf8Str &aLocale)
271{
272 RT_NOREF(aLocale);
273 return E_NOTIMPL;
274}
275
276HRESULT Unattended::getLanguage(com::Utf8Str &aLanguage)
277{
278 RT_NOREF(aLanguage);
279 return E_NOTIMPL;
280}
281
282HRESULT Unattended::setLanguage(const com::Utf8Str &aLanguage)
283{
284 RT_NOREF(aLanguage);
285 return E_NOTIMPL;
286}
287
288HRESULT Unattended::getCountry(com::Utf8Str &aCountry)
289{
290 RT_NOREF(aCountry);
291 return E_NOTIMPL;
292}
293
294HRESULT Unattended::setCountry(const com::Utf8Str &aCountry)
295{
296 RT_NOREF(aCountry);
297 return E_NOTIMPL;
298}
299
300HRESULT Unattended::getProxy(com::Utf8Str &aProxy)
301{
302 RT_NOREF(aProxy);
303 return E_NOTIMPL;
304}
305
306HRESULT Unattended::setProxy(const com::Utf8Str &aProxy)
307{
308 RT_NOREF(aProxy);
309 return E_NOTIMPL;
310}
311
312HRESULT Unattended::getPackageSelectionAdjustments(com::Utf8Str &aPackageSelectionAdjustments)
313{
314 RT_NOREF(aPackageSelectionAdjustments);
315 return E_NOTIMPL;
316}
317
318HRESULT Unattended::setPackageSelectionAdjustments(const com::Utf8Str &aPackageSelectionAdjustments)
319{
320 RT_NOREF(aPackageSelectionAdjustments);
321 return E_NOTIMPL;
322}
323
324HRESULT Unattended::getHostname(com::Utf8Str &aHostname)
325{
326 RT_NOREF(aHostname);
327 return E_NOTIMPL;
328}
329
330HRESULT Unattended::setHostname(const com::Utf8Str &aHostname)
331{
332 RT_NOREF(aHostname);
333 return E_NOTIMPL;
334}
335
336HRESULT Unattended::getAuxiliaryBasePath(com::Utf8Str &aAuxiliaryBasePath)
337{
338 RT_NOREF(aAuxiliaryBasePath);
339 return E_NOTIMPL;
340}
341
342HRESULT Unattended::setAuxiliaryBasePath(const com::Utf8Str &aAuxiliaryBasePath)
343{
344 RT_NOREF(aAuxiliaryBasePath);
345 return E_NOTIMPL;
346}
347
348HRESULT Unattended::getImageIndex(ULONG *index)
349{
350 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
351 *index = midxImage;
352 return S_OK;
353}
354
355HRESULT Unattended::setImageIndex(ULONG index)
356{
357 RT_NOREF(index);
358 return E_NOTIMPL;
359}
360
361HRESULT Unattended::getMachine(ComPtr<IMachine> &aMachine)
362{
363 RT_NOREF(aMachine);
364 return E_NOTIMPL;
365}
366
367HRESULT Unattended::setMachine(const ComPtr<IMachine> &aMachine)
368{
369 RT_NOREF(aMachine);
370 return E_NOTIMPL;
371}
372
373HRESULT Unattended::getScriptTemplatePath(com::Utf8Str &aScriptTemplatePath)
374{
375 RT_NOREF(aScriptTemplatePath);
376 return E_NOTIMPL;
377}
378
379HRESULT Unattended::setScriptTemplatePath(const com::Utf8Str &aScriptTemplatePath)
380{
381 RT_NOREF(aScriptTemplatePath);
382 return E_NOTIMPL;
383
384}
385
386HRESULT Unattended::getPostInstallScriptTemplatePath(com::Utf8Str &aPostInstallScriptTemplatePath)
387{
388 RT_NOREF(aPostInstallScriptTemplatePath);
389 return E_NOTIMPL;
390}
391
392HRESULT Unattended::setPostInstallScriptTemplatePath(const com::Utf8Str &aPostInstallScriptTemplatePath)
393{
394 RT_NOREF(aPostInstallScriptTemplatePath);
395 return E_NOTIMPL;
396}
397
398HRESULT Unattended::getPostInstallCommand(com::Utf8Str &aPostInstallCommand)
399{
400 RT_NOREF(aPostInstallCommand);
401 return E_NOTIMPL;
402}
403
404HRESULT Unattended::setPostInstallCommand(const com::Utf8Str &aPostInstallCommand)
405{
406 RT_NOREF(aPostInstallCommand);
407 return E_NOTIMPL;
408}
409
410HRESULT Unattended::getExtraInstallKernelParameters(com::Utf8Str &aExtraInstallKernelParameters)
411{
412 RT_NOREF(aExtraInstallKernelParameters);
413 return E_NOTIMPL;
414}
415
416HRESULT Unattended::setExtraInstallKernelParameters(const com::Utf8Str &aExtraInstallKernelParameters)
417{
418 RT_NOREF(aExtraInstallKernelParameters);
419 return E_NOTIMPL;
420}
421
422HRESULT Unattended::getDetectedOSTypeId(com::Utf8Str &aDetectedOSTypeId)
423{
424 RT_NOREF(aDetectedOSTypeId);
425 return E_NOTIMPL;
426}
427
428HRESULT Unattended::getDetectedOSVersion(com::Utf8Str &aDetectedOSVersion)
429{
430 RT_NOREF(aDetectedOSVersion);
431 return E_NOTIMPL;
432}
433
434HRESULT Unattended::getDetectedOSFlavor(com::Utf8Str &aDetectedOSFlavor)
435{
436 RT_NOREF(aDetectedOSFlavor);
437 return E_NOTIMPL;
438}
439
440HRESULT Unattended::getDetectedOSLanguages(com::Utf8Str &aDetectedOSLanguages)
441{
442 RT_NOREF(aDetectedOSLanguages);
443 return E_NOTIMPL;
444}
445
446HRESULT Unattended::getDetectedOSHints(com::Utf8Str &aDetectedOSHints)
447{
448 RT_NOREF(aDetectedOSHints);
449 return E_NOTIMPL;
450}
451
452HRESULT Unattended::getDetectedImageNames(std::vector<com::Utf8Str> &aDetectedImageNames)
453{
454 RT_NOREF(aDetectedImageNames);
455 return E_NOTIMPL;
456}
457
458HRESULT Unattended::getDetectedImageIndices(std::vector<ULONG> &aDetectedImageIndices)
459{
460 RT_NOREF(aDetectedImageIndices);
461 return E_NOTIMPL;
462}
463
464HRESULT Unattended::getIsUnattendedInstallSupported(BOOL *aIsUnattendedInstallSupported)
465{
466 RT_NOREF(aIsUnattendedInstallSupported);
467 return E_NOTIMPL;
468}
469
470HRESULT Unattended::getAvoidUpdatesOverNetwork(BOOL *aAvoidUpdatesOverNetwork)
471{
472 RT_NOREF(aAvoidUpdatesOverNetwork);
473 return E_NOTIMPL;
474}
475
476HRESULT Unattended::setAvoidUpdatesOverNetwork(BOOL aAvoidUpdatesOverNetwork)
477{
478 RT_NOREF(aAvoidUpdatesOverNetwork);
479 return E_NOTIMPL;
480}
481
482
483/*
484 * Getters that the installer and script classes can use.
485 */
486Utf8Str const &Unattended::i_getIsoPath() const
487{
488 return mStrIsoPath;
489}
490
491Utf8Str const &Unattended::i_getUser() const
492{
493 return mStrUser;
494}
495
496Utf8Str const &Unattended::i_getPassword() const
497{
498 return mStrPassword;
499}
500
501Utf8Str const &Unattended::i_getFullUserName() const
502{
503 return mStrFullUserName.isNotEmpty() ? mStrFullUserName : mStrUser;
504}
505
506Utf8Str const &Unattended::i_getProductKey() const
507{
508 return mStrProductKey;
509}
510
511Utf8Str const &Unattended::i_getProxy() const
512{
513 return mStrProxy;
514}
515
516Utf8Str const &Unattended::i_getAdditionsIsoPath() const
517{
518 return mStrAdditionsIsoPath;
519}
520
521bool Unattended::i_getInstallGuestAdditions() const
522{
523 return mfInstallGuestAdditions;
524}
525
526Utf8Str const &Unattended::i_getValidationKitIsoPath() const
527{
528 return mStrValidationKitIsoPath;
529}
530
531bool Unattended::i_getInstallTestExecService() const
532{
533 return mfInstallTestExecService;
534}
535
536Utf8Str const &Unattended::i_getTimeZone() const
537{
538 return mStrTimeZone;
539}
540
541PCRTTIMEZONEINFO Unattended::i_getTimeZoneInfo() const
542{
543 return mpTimeZoneInfo;
544}
545
546Utf8Str const &Unattended::i_getLocale() const
547{
548 return mStrLocale;
549}
550
551Utf8Str const &Unattended::i_getLanguage() const
552{
553 return mStrLanguage;
554}
555
556Utf8Str const &Unattended::i_getCountry() const
557{
558 return mStrCountry;
559}
560
561bool Unattended::i_isMinimalInstallation() const
562{
563 size_t i = mPackageSelectionAdjustments.size();
564 while (i-- > 0)
565 if (mPackageSelectionAdjustments[i].equals("minimal"))
566 return true;
567 return false;
568}
569
570Utf8Str const &Unattended::i_getHostname() const
571{
572 return mStrHostname;
573}
574
575Utf8Str const &Unattended::i_getAuxiliaryBasePath() const
576{
577 return mStrAuxiliaryBasePath;
578}
579
580ULONG Unattended::i_getImageIndex() const
581{
582 return midxImage;
583}
584
585Utf8Str const &Unattended::i_getScriptTemplatePath() const
586{
587 return mStrScriptTemplatePath;
588}
589
590Utf8Str const &Unattended::i_getPostInstallScriptTemplatePath() const
591{
592 return mStrPostInstallScriptTemplatePath;
593}
594
595Utf8Str const &Unattended::i_getPostInstallCommand() const
596{
597 return mStrPostInstallCommand;
598}
599
600Utf8Str const &Unattended::i_getAuxiliaryInstallDir() const
601{
602 static Utf8Str s_strAuxInstallDir("/aux/install/dir");
603 return s_strAuxInstallDir;
604}
605
606Utf8Str const &Unattended::i_getExtraInstallKernelParameters() const
607{
608 return mStrExtraInstallKernelParameters;
609}
610
611Utf8Str const &Unattended::i_getAdditionsInstallPackage() const
612{
613 return mStrAdditionsInstallPackage;
614}
615
616bool Unattended::i_isRtcUsingUtc() const
617{
618 return mfRtcUseUtc;
619}
620
621bool Unattended::i_isGuestOs64Bit() const
622{
623 return mfGuestOs64Bit;
624}
625
626bool Unattended::i_isFirmwareEFI() const
627{
628 return menmFirmwareType != FirmwareType_BIOS;
629}
630
631Utf8Str const &Unattended::i_getDetectedOSVersion()
632{
633 return mStrDetectedOSVersion;
634}
635
636bool Unattended::i_getAvoidUpdatesOverNetwork() const
637{
638 return mfAvoidUpdatesOverNetwork;
639}
640
641
642/*********************************************************************************************************************************
643* The Testcase *
644*********************************************************************************************************************************/
645
646static bool loadFileAsString(const char *pszFilename, Utf8Str &rstrContent)
647{
648 rstrContent.setNull();
649
650 char szPath[RTPATH_MAX];
651 RTTESTI_CHECK_RC_RET(RTPathExecDir(szPath, sizeof(szPath)), VINF_SUCCESS, false);
652 RTTESTI_CHECK_RC_RET(RTPathAppend(szPath, sizeof(szPath), pszFilename), VINF_SUCCESS, false);
653
654 RTFILE hFile;
655 RTTESTI_CHECK_RC_RET(RTFileOpen(&hFile, szPath, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE), VINF_SUCCESS, false);
656
657 uint64_t cbFile = 0;
658 RTTESTI_CHECK_RC_RET(RTFileQuerySize(hFile, &cbFile), VINF_SUCCESS, false);
659
660 rstrContent.reserve((size_t)cbFile + 1);
661 RTTESTI_CHECK_RC_RET(RTFileRead(hFile, rstrContent.mutableRaw(), (size_t)cbFile, NULL), VINF_SUCCESS, false);
662 rstrContent.mutableRaw()[cbFile] = '\0';
663 rstrContent.jolt();
664
665 RTTESTI_CHECK_RC_RET(RTFileClose(hFile), VINF_SUCCESS, false);
666
667 return true;
668}
669
670static void doTest1()
671{
672 RTTestISub("tstUnattendedScript-1.template");
673
674 /* Create the parent class instance: */
675 ComObjPtr<Unattended> ptrParent;
676 HRESULT hrc = ptrParent.createObject();
677 RTTESTI_CHECK_MSG_RETV(SUCCEEDED(hrc), ("hrc=%Rhrc\n", hrc));
678
679 /* Instantiate the script editor. */
680 UnattendedScriptTemplate Tmpl(ptrParent, "template.ext", "file.ext");
681#define CHECK_HRESULT(a_Expr) do { \
682 HRESULT hrcThis = a_Expr; \
683 if (SUCCEEDED(hrcThis)) break; \
684 RTTestIFailed("line %d: %s -> %Rhrc", __LINE__, #a_Expr, hrcThis); \
685 GlueHandleComError(ptrParent, NULL, hrcThis, NULL, __LINE__); \
686 } while (0)
687
688 /* Load the exercise script. */
689 char szPath[RTPATH_MAX];
690 RTTESTI_CHECK_RC_RETV(RTPathExecDir(szPath, sizeof(szPath)), VINF_SUCCESS);
691 RTTESTI_CHECK_RC_RETV(RTPathAppend(szPath, sizeof(szPath), "tstUnattendedScript-1.template"), VINF_SUCCESS);
692 CHECK_HRESULT(Tmpl.read(szPath));
693
694 /* Save the template to string. */
695 Utf8Str strActual;
696 CHECK_HRESULT(Tmpl.saveToString(strActual));
697
698 /* Load the expected result. */
699 Utf8Str strExpected;
700 RTTESTI_CHECK_RETV(loadFileAsString("tstUnattendedScript-1.expected", strExpected));
701
702 /* Compare the two. */
703 if (strExpected != strActual)
704 {
705 RTTestIFailed("Output does not match tstUnattendedScript-1.expect!");
706 RTTestIFailureDetails("------ BEGIN OUTPUT ------\n");
707 RTStrmWrite(g_pStdErr, strActual.c_str(), strActual.length());
708 RTTestIFailureDetails("------- END OUTPUT -------\n");
709
710 RTCList<RTCString, RTCString *> const lstActual = strActual.split("\n");
711 RTCList<RTCString, RTCString *> const lstExpected = strExpected.split("\n");
712 size_t const cLines = RT_MIN(lstActual.size(), lstExpected.size());
713 for (size_t i = 0; i < cLines; i++)
714 if (lstActual[i] != lstExpected[i])
715 {
716 RTTestIFailureDetails("First difference on line %u:\n%s\nexpected:\n%s\n",
717 i + 1, lstActual[i].c_str(), lstExpected[i].c_str());
718 break;
719 }
720 }
721}
722
723int main()
724{
725 RTTEST hTest;
726 RTEXITCODE rcExit = RTTestInitAndCreate("tstUnattendedScript", &hTest);
727 if (rcExit != RTEXITCODE_SUCCESS)
728 return rcExit;
729
730#ifdef RT_OS_WINDOWS
731 /*ATL::CComModule *g_pAtlComModule = */ new(ATL::CComModule);
732#endif
733
734 doTest1();
735
736 return RTTestSummaryAndDestroy(hTest);
737}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette