aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Util/ca/scasmbsched.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/Util/ca/scasmbsched.cpp')
-rw-r--r--src/ext/Util/ca/scasmbsched.cpp639
1 files changed, 639 insertions, 0 deletions
diff --git a/src/ext/Util/ca/scasmbsched.cpp b/src/ext/Util/ca/scasmbsched.cpp
new file mode 100644
index 00000000..e29f7f51
--- /dev/null
+++ b/src/ext/Util/ca/scasmbsched.cpp
@@ -0,0 +1,639 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5
6/********************************************************************
7 Helper functions to maintain a list of file shares to create / remove
8
9********************************************************************/
10SCA_SMB* NewSmb()
11{
12 SCA_SMB* pss = (SCA_SMB*)MemAlloc(sizeof(SCA_SMB), TRUE);
13 Assert(pss);
14 return pss;
15}
16
17
18SCA_SMB_EX_USER_PERMS* NewExUserPermsSmb()
19{
20 SCA_SMB_EX_USER_PERMS* pExUserPerms = (SCA_SMB_EX_USER_PERMS*)MemAlloc(sizeof(SCA_SMB_EX_USER_PERMS), TRUE);
21 Assert(pExUserPerms);
22 return pExUserPerms;
23}
24
25
26SCA_SMB* AddSmbToList(SCA_SMB* pssList, SCA_SMB* pss)
27{
28 if (pssList)
29 {
30 SCA_SMB* pssT = pssList;
31 while (pssT->pssNext)
32 {
33 pssT = pssT->pssNext;
34 }
35
36 pssT->pssNext = pss;
37 }
38 else
39 {
40 pssList = pss;
41 }
42
43 return pssList;
44}
45
46
47SCA_SMB_EX_USER_PERMS* AddExUserPermsSmbToList(
48 SCA_SMB_EX_USER_PERMS* pExUserPermsList,
49 SCA_SMB_EX_USER_PERMS* pExUserPerms
50 )
51{
52 SCA_SMB_EX_USER_PERMS* pExUserPermsTemp = pExUserPermsList;
53 if (pExUserPermsList)
54 {
55 while (pExUserPermsTemp->pExUserPermsNext)
56 {
57 pExUserPermsTemp = pExUserPermsTemp->pExUserPermsNext;
58 }
59
60 pExUserPermsTemp->pExUserPermsNext = pExUserPerms;
61 }
62 else
63 {
64 pExUserPermsList = pExUserPerms;
65 }
66
67 return pExUserPermsList;
68}
69
70void ScaSmbFreeList(SCA_SMB* pssList)
71{
72 SCA_SMB* pssDelete = pssList;
73 while (pssList)
74 {
75 pssDelete = pssList;
76 pssList = pssList->pssNext;
77
78 MemFree(pssDelete);
79 }
80}
81
82void ScaExUserPermsSmbFreeList(SCA_SMB_EX_USER_PERMS* pExUserPermsList)
83{
84 SCA_SMB_EX_USER_PERMS* pExUserPermsDelete = pExUserPermsList;
85 while (pExUserPermsList)
86 {
87 pExUserPermsDelete = pExUserPermsList;
88 pExUserPermsList = pExUserPermsList->pExUserPermsNext;
89
90 MemFree(pExUserPermsDelete);
91 }
92}
93
94// sql query constants
95LPCWSTR vcsSmbQuery = L"SELECT `Wix4FileShare`, `ShareName`, `Description`, `Directory_`, "
96 L"`Component_`, `User_`, `Permissions` FROM `Wix4FileShare`";
97
98enum eSmbQuery {
99 ssqFileShare = 1,
100 ssqShareName,
101 ssqDescription,
102 ssqDirectory,
103 ssqComponent,
104 ssqUser,
105 ssqPermissions
106 };
107
108
109/********************************************************************
110 ScaSmbRead - read all of the information from the msi tables and
111 return a list of file share jobs to be done.
112
113********************************************************************/
114HRESULT ScaSmbRead(SCA_SMB** ppssList)
115{
116 HRESULT hr = S_OK;
117 UINT er = ERROR_SUCCESS;
118 PMSIHANDLE hView, hRec;
119
120 LPWSTR pwzData = NULL;
121
122 SCA_SMB* pss = NULL;
123 BOOL bUserPermissionsTableExists = FALSE;
124
125 if (S_OK != WcaTableExists(L"Wix4FileShare"))
126 {
127 WcaLog(LOGMSG_VERBOSE, "Skipping ScaSmbCreateShare() - Wix4FileShare table not present");
128 ExitFunction1(hr = S_FALSE);
129 }
130
131 if (S_OK == WcaTableExists(L"Wix4FileSharePermissions"))
132 {
133 bUserPermissionsTableExists = TRUE;
134 }
135 else
136 {
137 WcaLog(LOGMSG_VERBOSE, "No Additional Permissions - Wix4FileSharePermissions table not present");
138 }
139
140 WcaLog(LOGMSG_VERBOSE, "Reading File Share Tables");
141
142 // loop through all the fileshares
143 hr = WcaOpenExecuteView(vcsSmbQuery, &hView);
144 ExitOnFailure(hr, "Failed to open view on Wix4FileShare table");
145 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
146 {
147 pss = NewSmb();
148 if (!pss)
149 {
150 hr = E_OUTOFMEMORY;
151 break;
152 }
153 Assert(pss);
154 ::ZeroMemory(pss, sizeof(*pss));
155
156 hr = WcaGetRecordString(hRec, ssqFileShare, &pwzData);
157 ExitOnFailure(hr, "Failed to get Wix4FileShare.Wix4FileShare");
158 hr = ::StringCchCopyW(pss->wzId, countof(pss->wzId), pwzData);
159 ExitOnFailure(hr, "Failed to copy ID string to smb object");
160
161 hr = WcaGetRecordFormattedString(hRec, ssqShareName, &pwzData);
162 ExitOnFailure(hr, "Failed to get Wix4FileShare.ShareName");
163 hr = ::StringCchCopyW(pss->wzShareName, countof(pss->wzShareName), pwzData);
164 ExitOnFailure(hr, "Failed to copy share name string to smb object");
165
166 hr = WcaGetRecordString(hRec, ssqComponent, &pwzData);
167 ExitOnFailure(hr, "Failed to get Component for Wix4FileShare: '%ls'", pss->wzShareName);
168 hr = ::StringCchCopyW(pss->wzComponent, countof(pss->wzComponent), pwzData);
169 ExitOnFailure(hr, "Failed to copy component string to smb object");
170
171 hr = WcaGetRecordFormattedString(hRec, ssqDescription, &pwzData);
172 ExitOnFailure(hr, "Failed to get Share Description for Wix4FileShare: '%ls'", pss->wzShareName);
173 hr = ::StringCchCopyW(pss->wzDescription, countof(pss->wzDescription), pwzData);
174 ExitOnFailure(hr, "Failed to copy description string to smb object");
175
176 // get user info from the user table
177 hr = WcaGetRecordFormattedString(hRec, ssqUser, &pwzData);
178 ExitOnFailure(hr, "Failed to get Wix4User record for Wix4FileShare: '%ls'", pss->wzShareName);
179
180 // get component install state
181 er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pss->wzComponent, &pss->isInstalled, &pss->isAction);
182 hr = HRESULT_FROM_WIN32(er);
183 ExitOnFailure(hr, "Failed to get Component state for Wix4FileShare");
184
185 // if a user was specified
186 if (*pwzData)
187 {
188 pss->fUseIntegratedAuth = FALSE;
189 pss->fLegacyUserProvided = TRUE;
190 hr = ScaGetUser(pwzData, &pss->scau);
191 ExitOnFailure(hr, "Failed to get user information for fileshare: '%ls'", pss->wzShareName);
192 }
193 else
194 {
195 pss->fLegacyUserProvided = FALSE;
196 // TODO: figure out whether this is useful still
197 //pss->fUseIntegratedAuth = TRUE;
198 // integrated authorization doesn't have a User record
199 }
200
201 // get the share's directory
202 hr = WcaGetRecordString(hRec, ssqDirectory, &pwzData);
203 ExitOnFailure(hr, "Failed to get directory for Wix4FileShare: '%ls'", pss->wzShareName);
204
205 WCHAR wzPath[MAX_PATH];
206 DWORD dwLen;
207 dwLen = countof(wzPath);
208 // review: relevant for file shares?
209 if (INSTALLSTATE_SOURCE == pss->isAction)
210 {
211 er = ::MsiGetSourcePathW(WcaGetInstallHandle(), pwzData, wzPath, &dwLen);
212 }
213 else
214 {
215 er = ::MsiGetTargetPathW(WcaGetInstallHandle(), pwzData, wzPath, &dwLen);
216 }
217 hr = HRESULT_FROM_WIN32(er);
218 ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory");
219
220 // If the path is to the root of a drive, then it needs a trailing backslash.
221 // Otherwise, it can't have a trailing backslash.
222 if (3 < dwLen)
223 {
224 if (wzPath[dwLen - 1] == L'\\')
225 {
226 wzPath[dwLen - 1] = 0;
227 }
228 }
229 else if (2 == dwLen && wzPath[1] == L':')
230 {
231 wzPath[2] = L'\\';
232 wzPath[3] = 0;
233 }
234
235 hr = ::StringCchCopyW(pss->wzDirectory, countof(pss->wzDirectory), wzPath);
236 ExitOnFailure(hr, "Failed to copy directory string to smb object");
237
238 hr = WcaGetRecordInteger(hRec, ssqPermissions, &pss->nPermissions);
239 ExitOnFailure(hr, "Failed to get Wix4FileShare.Permissions");
240
241 // Check to see if additional user & permissions are specified for this share
242 if (bUserPermissionsTableExists)
243 {
244 hr = ScaSmbExPermsRead(pss);
245 ExitOnFailure(hr, "Failed to get Additional File Share Permissions");
246 }
247
248 *ppssList = AddSmbToList(*ppssList, pss);
249 pss = NULL; // set the smb NULL so it doesn't accidentally get freed below
250 }
251
252 if (E_NOMOREITEMS == hr)
253 {
254 hr = S_OK;
255 }
256 ExitOnFailure(hr, "Failure occured while processing Wix4FileShare table");
257
258LExit:
259 // if anything was left over after an error clean it all up
260 if (pss)
261 {
262 ScaSmbFreeList(pss);
263 }
264
265 ReleaseStr(pwzData);
266
267 return hr;
268}
269
270
271/********************************************************************
272 RetrieveSMBShareUserPermList - retrieve SMB Share's user permission list
273
274********************************************************************/
275HRESULT RetrieveFileShareUserPerm(SCA_SMB* pss, SCA_SMB_EX_USER_PERMS** ppExUserPermsList, DWORD *pUserPermsCount)
276{
277 HRESULT hr = S_OK;
278 SHARE_INFO_502* psi = NULL;
279 NET_API_STATUS s;
280 BOOL bValid, bDaclDefaulted;
281 PACL acl = NULL;
282 PEXPLICIT_ACCESSW pEA = NULL;
283 ULONG nCount = 0;
284 DWORD er = ERROR_SUCCESS;
285 PSID pSID = NULL;
286 DWORD nUserNameSize = MAX_DARWIN_COLUMN;
287 DWORD nDomainNameSize = MAX_DARWIN_COLUMN;
288 SID_NAME_USE peUse;
289 DWORD dwCounter = 0;
290 SCA_SMB_EX_USER_PERMS* pExUserPermsList = NULL;
291 DWORD dwUserPermsCount = 0;
292
293 *pUserPermsCount = 0;
294 s = ::NetShareGetInfo(NULL, pss->wzShareName, 502, (LPBYTE*)&psi);
295 WcaLog(LOGMSG_VERBOSE, "retrieving permissions on existing file share.");
296 if (NERR_NetNameNotFound == s)
297 {
298 WcaLog(LOGMSG_VERBOSE, "File share has already been removed.");
299 ExitFunction1(hr = S_OK);
300 }
301 else if (NERR_Success != s || psi == NULL)
302 {
303 hr = E_FAIL;
304 ExitOnFailure(hr, "Failed to get share information with return code: %d", s);
305 }
306 if (!::GetSecurityDescriptorDacl(psi->shi502_security_descriptor, &bValid, &acl, &bDaclDefaulted) || !bValid)
307 {
308 ExitOnLastError(hr, "Failed to get acl from security descriptor");
309 }
310
311 er = ::GetExplicitEntriesFromAclW(acl, &nCount, &pEA);
312 hr = HRESULT_FROM_WIN32(er);
313 ExitOnFailure(hr, "Failed to get access entries from acl for file share %ls", pss->wzShareName);
314 for (dwCounter = 0; dwCounter < nCount; ++dwCounter)
315 {
316 if (TRUSTEE_IS_SID == pEA[dwCounter].Trustee.TrusteeForm)
317 {
318 SCA_SMB_EX_USER_PERMS* pExUserPerms = NewExUserPermsSmb();
319 ::ZeroMemory(pExUserPerms, sizeof(*pExUserPerms));
320 pExUserPermsList = AddExUserPermsSmbToList(pExUserPermsList, pExUserPerms);
321 pSID = (PSID)(pEA[dwCounter].Trustee.ptstrName);
322 if (!::LookupAccountSidW(NULL, pSID, pExUserPerms->scau.wzName, &nUserNameSize, pExUserPerms->scau.wzDomain, &nDomainNameSize, &peUse))
323 {
324 hr = E_FAIL;
325 ExitOnFailure(hr, "Failed to get account name from SID");
326 }
327 pExUserPerms->nPermissions = pEA[dwCounter].grfAccessPermissions;
328 pExUserPerms->accessMode = pEA[dwCounter].grfAccessMode;
329 ++dwUserPermsCount;
330 nUserNameSize = MAX_DARWIN_COLUMN;
331 nDomainNameSize = MAX_DARWIN_COLUMN;
332 }
333 }
334 *ppExUserPermsList = pExUserPermsList;
335 *pUserPermsCount = dwUserPermsCount;
336
337LExit:
338 if (psi)
339 {
340 ::NetApiBufferFree(psi);
341 }
342
343 if (pEA)
344 {
345 ::LocalFree(pEA);
346 }
347
348 return hr;
349}
350
351
352/********************************************************************
353 SchedCreateSmb - schedule one instance of a file share creation
354
355********************************************************************/
356HRESULT SchedCreateSmb(SCA_SMB* pss)
357{
358 HRESULT hr = S_OK;
359
360 WCHAR wzDomainUser[255]; // "domain\user"
361 SCA_SMB_EX_USER_PERMS* pExUserPermsList = NULL;
362 int nCounter = 0;
363 WCHAR* pwzRollbackCustomActionData = NULL;
364 WCHAR* pwzCustomActionData = NULL;
365
366 hr = WcaWriteStringToCaData(pss->wzShareName, &pwzRollbackCustomActionData);
367 ExitOnFailure(hr, "failed to add ShareName to CustomActionData");
368
369 hr = WcaWriteStringToCaData(pss->wzShareName, &pwzCustomActionData);
370 ExitOnFailure(hr, "failed to add ShareName to CustomActionData");
371
372 hr = WcaWriteStringToCaData(pss->wzDescription, &pwzCustomActionData);
373 ExitOnFailure(hr, "Failed to add server name to CustomActionData");
374
375 hr = WcaWriteStringToCaData(pss->wzDirectory, &pwzCustomActionData);
376 ExitOnFailure(hr, "Failed to add full path instance to CustomActionData");
377
378 hr = WcaWriteStringToCaData(pss->fUseIntegratedAuth ? L"1" : L"0", &pwzCustomActionData);
379 ExitOnFailure(hr, "Failed to add server name to CustomActionData");
380
381 if (pss->fLegacyUserProvided)
382 {
383 hr = WcaWriteIntegerToCaData(pss->nUserPermissionCount + 1, &pwzCustomActionData);
384 ExitOnFailure(hr, "Failed to add additional user permission count to CustomActionData");
385
386 hr = UserBuildDomainUserName(wzDomainUser, countof(wzDomainUser), pss->scau.wzName, pss->scau.wzDomain);
387 ExitOnFailure(hr, "Failed to build user and domain name for CustomActionData");
388 hr = WcaWriteStringToCaData(wzDomainUser, &pwzCustomActionData);
389 ExitOnFailure(hr, "Failed to add server Domain\\UserName to CustomActionData");
390
391 hr = WcaWriteIntegerToCaData(pss->nPermissions, &pwzCustomActionData);
392 ExitOnFailure(hr, "Failed to add permissions to CustomActionData");
393 }
394 else
395 {
396 hr = WcaWriteIntegerToCaData(pss->nUserPermissionCount, &pwzCustomActionData);
397 ExitOnFailure(hr, "Failed to add additional user permission count to CustomActionData");
398 }
399
400 if (pss->nUserPermissionCount > 0)
401 {
402 nCounter = 0;
403 for (pExUserPermsList = pss->pExUserPerms; pExUserPermsList; pExUserPermsList = pExUserPermsList->pExUserPermsNext)
404 {
405 Assert(nCounter < pss->nUserPermissionCount);
406
407 hr = UserBuildDomainUserName(wzDomainUser, countof(wzDomainUser), pExUserPermsList->scau.wzName, pExUserPermsList->scau.wzDomain);
408 ExitOnFailure(hr, "Failed to build user and domain name for CustomActionData");
409 hr = WcaWriteStringToCaData(wzDomainUser, &pwzCustomActionData);
410 ExitOnFailure(hr, "Failed to add server Domain\\UserName to CustomActionData");
411
412 hr = WcaWriteIntegerToCaData((int)pExUserPermsList->accessMode, &pwzCustomActionData);
413 ExitOnFailure(hr, "Failed to add access mode to CustomActionData");
414
415 hr = WcaWriteIntegerToCaData(pExUserPermsList->nPermissions, &pwzCustomActionData);
416 ExitOnFailure(hr, "Failed to add permissions to CustomActionData");
417 ++nCounter;
418 }
419 Assert(nCounter == pss->nUserPermissionCount);
420 }
421
422 // Schedule the rollback first
423 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"CreateSmbRollback"), pwzRollbackCustomActionData, COST_SMB_DROPSMB);
424 ExitOnFailure(hr, "Failed to schedule DropSmb action");
425
426 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"CreateSmb"), pwzCustomActionData, COST_SMB_CREATESMB);
427 ExitOnFailure(hr, "Failed to schedule CreateSmb action");
428
429LExit:
430 ReleaseStr(pwzRollbackCustomActionData);
431 ReleaseStr(pwzCustomActionData);
432
433 if (pExUserPermsList)
434 {
435 ScaExUserPermsSmbFreeList(pExUserPermsList);
436 }
437
438 return hr;
439}
440
441
442/********************************************************************
443 ScaSmbInstall - for every file share, schedule the create custom action
444
445********************************************************************/
446HRESULT ScaSmbInstall(SCA_SMB* pssList)
447{
448 HRESULT hr = S_FALSE; // assume nothing will be done
449 SCA_SMB* pss = NULL;
450
451 for (pss = pssList; pss; pss = pss->pssNext)
452 {
453 // if installing this component
454 if (WcaIsInstalling(pss->isInstalled, pss->isAction) )
455 {
456 hr = SchedCreateSmb(pss);
457 ExitOnFailure(hr, "Failed to schedule the creation of the fileshare: %ls", pss->wzShareName);
458 }
459 }
460
461LExit:
462 return hr;
463}
464
465
466/********************************************************************
467 SchedDropSmb - schedule one instance of a file share removal
468
469********************************************************************/
470HRESULT SchedDropSmb(SCA_SMB* pss)
471{
472 HRESULT hr = S_OK;
473
474 WCHAR* pwzCustomActionData = NULL;
475 WCHAR* pwzRollbackCustomActionData = NULL;
476 SCA_SMB_EX_USER_PERMS *pExUserPermsList = NULL;
477 SCA_SMB_EX_USER_PERMS *pExUserPerm = NULL;
478 WCHAR wzDomainUser[255]; // "domain\user"
479 DWORD dwUserPermsCount = 0;
480
481 // roll back DropSmb
482 hr = WcaWriteStringToCaData(pss->wzShareName, &pwzRollbackCustomActionData);
483 ExitOnFailure(hr, "failed to add ShareName to CustomActionData");
484
485 hr = WcaWriteStringToCaData(pss->wzDescription, &pwzRollbackCustomActionData);
486 ExitOnFailure(hr, "Failed to add server name to CustomActionData");
487
488 hr = WcaWriteStringToCaData(pss->wzDirectory, &pwzRollbackCustomActionData);
489 ExitOnFailure(hr, "Failed to add full path instance to CustomActionData");
490
491 hr = WcaWriteStringToCaData(L"1", &pwzRollbackCustomActionData);
492 ExitOnFailure(hr, "Failed to add useintegrated flag to CustomActionData");
493
494 hr = RetrieveFileShareUserPerm(pss, &pExUserPermsList, &dwUserPermsCount);
495 ExitOnFailure(hr, "Failed to retrieve SMBShare's user permissions");
496
497 hr = WcaWriteIntegerToCaData((int)dwUserPermsCount, &pwzRollbackCustomActionData);
498 ExitOnFailure(hr, "Failed to add additional user permission count to CustomActionData");
499
500 for (pExUserPerm = pExUserPermsList; pExUserPerm; pExUserPerm = pExUserPerm->pExUserPermsNext)
501 {
502 hr = UserBuildDomainUserName(wzDomainUser, countof(wzDomainUser), pExUserPerm->scau.wzName, pExUserPerm->scau.wzDomain);
503 ExitOnFailure(hr, "Failed to build user and domain name for CustomActionData");
504 hr = WcaWriteStringToCaData(wzDomainUser, &pwzRollbackCustomActionData);
505 ExitOnFailure(hr, "Failed to add server Domain\\UserName to CustomActionData");
506
507 hr = WcaWriteIntegerToCaData((int)pExUserPerm->accessMode, &pwzRollbackCustomActionData);
508 ExitOnFailure(hr, "Failed to add access mode to CustomActionData");
509
510 hr = WcaWriteIntegerToCaData(pExUserPerm->nPermissions, &pwzRollbackCustomActionData);
511 ExitOnFailure(hr, "Failed to add permissions to CustomActionData");
512 }
513
514 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"DropSmbRollback"), pwzRollbackCustomActionData, COST_SMB_CREATESMB);
515 ExitOnFailure(hr, "Failed to schedule DropSmbRollback action");
516
517 // DropSMB
518 hr = WcaWriteStringToCaData(pss->wzShareName, &pwzCustomActionData);
519 ExitOnFailure(hr, "failed to add ShareName to CustomActionData");
520
521 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"DropSmb"), pwzCustomActionData, COST_SMB_DROPSMB);
522 ExitOnFailure(hr, "Failed to schedule DropSmb action");
523
524LExit:
525 ReleaseStr(pwzCustomActionData);
526
527 if (pExUserPermsList)
528 {
529 ScaExUserPermsSmbFreeList(pExUserPermsList);
530 }
531
532 return hr;
533
534}
535
536
537/********************************************************************
538 ScaSmbUninstall - for every file share, schedule the drop custom action
539
540********************************************************************/
541HRESULT ScaSmbUninstall(SCA_SMB* pssList)
542{
543 HRESULT hr = S_FALSE; // assume nothing will be done
544 SCA_SMB* pss = NULL;
545
546 for (pss = pssList; pss; pss = pss->pssNext)
547 {
548 // if uninstalling this component
549 if (WcaIsUninstalling(pss->isInstalled, pss->isAction) )
550 {
551 hr = SchedDropSmb(pss);
552 ExitOnFailure(hr, "Failed to remove file share %ls", pss->wzShareName);
553 }
554 }
555
556LExit:
557 return hr;
558}
559
560LPCWSTR vcsSmbExUserPermsQuery = L"SELECT `FileShare_`,`User_`,`Permissions` "
561 L"FROM `Wix4FileSharePermissions` WHERE `FileShare_`=?";
562
563enum eSmbUserPermsQuery {
564 ssupqFileShare = 1,
565 ssupqUser,
566 ssupqPermissions
567
568};
569
570
571/********************************************************************
572 ScaSmbExPermsRead - for Every entry in File Permissions table add a
573 User Name & Permissions structure to the List
574
575********************************************************************/
576HRESULT ScaSmbExPermsRead(SCA_SMB* pss)
577{
578 HRESULT hr = S_OK;
579 PMSIHANDLE hView, hRec;
580
581 LPWSTR pwzData = NULL;
582 SCA_SMB_EX_USER_PERMS* pExUserPermsList = pss->pExUserPerms;
583 SCA_SMB_EX_USER_PERMS* pExUserPerms = NULL;
584 int nCounter = 0;
585
586 hRec = ::MsiCreateRecord(1);
587 hr = WcaSetRecordString(hRec, 1, pss->wzId);
588 ExitOnFailure(hr, "Failed to look up FileShare");
589
590 hr = WcaOpenView(vcsSmbExUserPermsQuery, &hView);
591 ExitOnFailure(hr, "Failed to open view on Wix4FileSharePermissions table");
592 hr = WcaExecuteView(hView, hRec);
593 ExitOnFailure(hr, "Failed to execute view on Wix4FileSharePermissions table");
594
595 // loop through all User/Permissions paris returned
596 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
597 {
598 pExUserPerms = NewExUserPermsSmb();
599 if (!pExUserPerms)
600 {
601 hr = E_OUTOFMEMORY;
602 break;
603 }
604 Assert(pExUserPerms);
605 ::ZeroMemory(pExUserPerms, sizeof(*pExUserPerms));
606
607 hr = WcaGetRecordString(hRec, ssupqUser, &pwzData);
608 ExitOnFailure(hr, "Failed to get Wix4FileSharePermissions.User");
609 hr = ScaGetUser(pwzData, &pExUserPerms->scau);
610 ExitOnFailure(hr, "Failed to get user information for fileshare: '%ls'", pss->wzShareName);
611
612 hr = WcaGetRecordInteger(hRec, ssupqPermissions, &pExUserPerms->nPermissions);
613 ExitOnFailure(hr, "Failed to get Wix4FileSharePermissions.Permissions");
614 pExUserPerms->accessMode = SET_ACCESS; // we only support SET_ACCESS here
615
616 pExUserPermsList = AddExUserPermsSmbToList(pExUserPermsList, pExUserPerms);
617 ++nCounter;
618 pExUserPerms = NULL; // set the smb NULL so it doesn't accidentally get freed below
619 }
620
621 if (E_NOMOREITEMS == hr)
622 {
623 hr = S_OK;
624 pss->pExUserPerms = pExUserPermsList;
625 pss->nUserPermissionCount = nCounter;
626 }
627 ExitOnFailure(hr, "Failure occured while processing FileShare table");
628
629LExit:
630 // if anything was left over after an error clean it all up
631 if (pExUserPerms)
632 {
633 ScaExUserPermsSmbFreeList(pExUserPerms);
634 }
635
636 ReleaseStr(pwzData);
637
638 return hr;
639}