/*
- * @unimplemented
+ * @implemented
*/
BOOL
STDCALL
GUID* InheritedObjectTypeGuid,
PSID pSid)
{
- DPRINT1("%s() not implemented!\n", __FUNCTION__);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+
+ Status = RtlAddAccessAllowedObjectAce(pAcl,
+ dwAceRevision,
+ AceFlags,
+ AccessMask,
+ ObjectTypeGuid,
+ InheritedObjectTypeGuid,
+ pSid);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ return TRUE;
}
/*
- * @unimplemented
+ * @implemented
*/
BOOL
STDCALL
GUID* InheritedObjectTypeGuid,
PSID pSid)
{
- DPRINT1("%s() not implemented!\n", __FUNCTION__);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+
+ Status = RtlAddAccessDeniedObjectAce(pAcl,
+ dwAceRevision,
+ AceFlags,
+ AccessMask,
+ ObjectTypeGuid,
+ InheritedObjectTypeGuid,
+ pSid);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ return TRUE;
}
/*
- * @unimplemented
+ * @implemented
*/
BOOL
STDCALL
BOOL bAuditSuccess,
BOOL bAuditFailure)
{
- DPRINT1("%s() not implemented!\n", __FUNCTION__);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+
+ Status = RtlAddAuditAccessObjectAce(pAcl,
+ dwAceRevision,
+ AceFlags,
+ AccessMask,
+ ObjectTypeGuid,
+ InheritedObjectTypeGuid,
+ pSid,
+ bAuditSuccess,
+ bAuditFailure);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ return TRUE;
}
}
-/*
- * @implemented
- */
-DWORD
-STDCALL
-SetEntriesInAclA(
- ULONG cCountOfExplicitEntries,
- PEXPLICIT_ACCESS_A pListOfExplicitEntries,
- PACL OldAcl,
- PACL* NewAcl)
+static DWORD
+InternalTrusteeAToW(IN PTRUSTEE_A pTrusteeA,
+ OUT PTRUSTEE_W *pTrusteeW)
{
- PEXPLICIT_ACCESS_W ListOfExplicitEntriesW;
- ULONG i;
- DWORD ErrorCode;
+ TRUSTEE_FORM TrusteeForm;
+ INT BufferSize = 0;
+ PSTR lpStr;
+ DWORD ErrorCode = ERROR_SUCCESS;
- if (cCountOfExplicitEntries != 0)
+ ASSERT(sizeof(TRUSTEE_W) == sizeof(TRUSTEE_A));
+
+ TrusteeForm = GetTrusteeForm(pTrusteeA);
+ switch (TrusteeForm)
{
- ListOfExplicitEntriesW = HeapAlloc(GetProcessHeap(),
- 0,
- cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W));
- if (ListOfExplicitEntriesW != NULL)
+ case TRUSTEE_IS_NAME:
{
/* directly copy the array, this works as the size of the EXPLICIT_ACCESS_A
structure matches the size of the EXPLICIT_ACCESS_W version */
- ASSERT(sizeof(EXPLICIT_ACCESS_A) == sizeof(EXPLICIT_ACCESS_W));
-
- RtlCopyMemory(ListOfExplicitEntriesW,
- pListOfExplicitEntries,
- cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W));
+ lpStr = GetTrusteeName(pTrusteeA);
+ if (lpStr != NULL)
+ BufferSize = strlen(lpStr) + 1;
- /* convert the trustee names if required */
- for (i = 0; i != cCountOfExplicitEntries; i++)
+ *pTrusteeW = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ sizeof(TRUSTEE_W) + (BufferSize * sizeof(WCHAR)));
+ if (*pTrusteeW != NULL)
{
- if (pListOfExplicitEntries[i].Trustee.TrusteeForm == TRUSTEE_IS_NAME)
+ RtlCopyMemory(*pTrusteeW,
+ pTrusteeA,
+ FIELD_OFFSET(TRUSTEE_A,
+ ptstrName));
+
+ if (lpStr != NULL)
{
- UINT BufCount = strlen(pListOfExplicitEntries[i].Trustee.ptstrName) + 1;
- ListOfExplicitEntriesW[i].Trustee.ptstrName =
- (LPWSTR)HeapAlloc(GetProcessHeap(),
- 0,
- BufCount * sizeof(WCHAR));
-
- if (ListOfExplicitEntriesW[i].Trustee.ptstrName == NULL ||
- MultiByteToWideChar(CP_ACP,
+ (*pTrusteeW)->ptstrName = (PWSTR)((*pTrusteeW) + 1);
+
+ /* convert the trustee's name */
+ if (MultiByteToWideChar(CP_ACP,
0,
- pListOfExplicitEntries[i].Trustee.ptstrName,
+ lpStr,
-1,
- ListOfExplicitEntriesW[i].Trustee.ptstrName,
- BufCount) == 0)
+ (*pTrusteeW)->ptstrName,
+ BufferSize) == 0)
{
- /* failed to allocate enough momory for the strings or failed to
- convert the ansi string to unicode, then fail and free all
- allocated memory */
+ goto ConvertErr;
+ }
+ }
+ else
+ {
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ *pTrusteeW);
+ goto NothingToConvert;
+ }
+ }
+ else
+ ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ break;
+ }
- ErrorCode = GetLastError();
+ case TRUSTEE_IS_OBJECTS_AND_NAME:
+ {
+ POBJECTS_AND_NAME_A oanA = (POBJECTS_AND_NAME_A)GetTrusteeNameA(pTrusteeA);
+ POBJECTS_AND_NAME_W oan;
+ PWSTR StrBuf;
- do
- {
- if (ListOfExplicitEntriesW[i].Trustee.TrusteeForm == TRUSTEE_IS_NAME &&
- ListOfExplicitEntriesW[i].Trustee.ptstrName != NULL)
- {
- HeapFree(GetProcessHeap(),
+ /* calculate the size needed */
+ if ((oanA->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
+ oanA->InheritedObjectTypeName != NULL)
+ {
+ BufferSize = strlen(oanA->InheritedObjectTypeName) + 1;
+ }
+ if (oanA->ptstrName != NULL)
+ {
+ BufferSize += strlen(oanA->ptstrName) + 1;
+ }
+
+ *pTrusteeW = RtlAllocateHeap(RtlGetProcessHeap(),
0,
- ListOfExplicitEntriesW[i].Trustee.ptstrName);
- }
- } while (i-- != 0);
+ sizeof(TRUSTEE_W) + sizeof(OBJECTS_AND_NAME_W) +
+ (BufferSize * sizeof(WCHAR)));
- /* free the allocated array */
- HeapFree(GetProcessHeap(),
- 0,
- ListOfExplicitEntriesW);
+ if (*pTrusteeW != NULL)
+ {
+ oan = (POBJECTS_AND_NAME_W)((*pTrusteeW) + 1);
+ StrBuf = (PWSTR)(oan + 1);
+
+ /* copy over the parts of the TRUSTEE structure that don't need
+ to be touched */
+ RtlCopyMemory(*pTrusteeW,
+ pTrusteeA,
+ FIELD_OFFSET(TRUSTEE_A,
+ ptstrName));
+
+ (*pTrusteeW)->ptstrName = (LPWSTR)oan;
+
+ /* convert the OBJECTS_AND_NAME_A structure */
+ oan->ObjectsPresent = oanA->ObjectsPresent;
+ oan->ObjectType = oanA->ObjectType;
+
+ if ((oanA->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
+ oanA->InheritedObjectTypeName != NULL)
+ {
+ /* convert inherited object type name */
+ BufferSize = strlen(oanA->InheritedObjectTypeName) + 1;
+
+ if (MultiByteToWideChar(CP_ACP,
+ 0,
+ oanA->InheritedObjectTypeName,
+ -1,
+ StrBuf,
+ BufferSize) == 0)
+ {
+ goto ConvertErr;
+ }
+ oan->InheritedObjectTypeName = StrBuf;
+
+ StrBuf += BufferSize;
+ }
+ else
+ oan->InheritedObjectTypeName = NULL;
+
+ if (oanA->ptstrName != NULL)
+ {
+ /* convert the trustee name */
+ BufferSize = strlen(oanA->ptstrName) + 1;
+
+ if (MultiByteToWideChar(CP_ACP,
+ 0,
+ oanA->ptstrName,
+ -1,
+ StrBuf,
+ BufferSize) == 0)
+ {
+ConvertErr:
+ ErrorCode = GetLastError();
+
+ /* cleanup */
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ *pTrusteeW);
return ErrorCode;
}
+ oan->ptstrName = StrBuf;
}
+ else
+ oan->ptstrName = NULL;
}
+ else
+ ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ break;
}
- else
+
+ default:
{
- return GetLastError();
+NothingToConvert:
+ /* no need to convert anything to unicode */
+ *pTrusteeW = (PTRUSTEE_W)pTrusteeA;
+ break;
}
}
- else
- ListOfExplicitEntriesW = NULL;
- ErrorCode = SetEntriesInAclW(cCountOfExplicitEntries,
- ListOfExplicitEntriesW,
- OldAcl,
- NewAcl);
+ return ErrorCode;
+}
+
+
+static __inline VOID
+InternalFreeConvertedTrustee(IN PTRUSTEE_W pTrusteeW,
+ IN PTRUSTEE_A pTrusteeA)
+{
+ if ((PVOID)pTrusteeW != (PVOID)pTrusteeA)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ pTrusteeW);
+ }
+}
+
- /* free the strings */
- if (ListOfExplicitEntriesW != NULL)
+static DWORD
+InternalExplicitAccessAToW(IN ULONG cCountOfExplicitEntries,
+ IN PEXPLICIT_ACCESS_A pListOfExplicitEntriesA,
+ OUT PEXPLICIT_ACCESS_W *pListOfExplicitEntriesW)
+{
+ TRUSTEE_FORM TrusteeForm;
+ SIZE_T Size;
+ ULONG i;
+ ULONG ObjectsAndNameCount = 0;
+ PEXPLICIT_ACCESS_W peaw = NULL;
+ DWORD ErrorCode = ERROR_SUCCESS;
+ LPSTR lpStr;
+
+ /* NOTE: This code assumes that the size of the TRUSTEE_A and TRUSTEE_W structure matches! */
+ ASSERT(sizeof(TRUSTEE_A) == sizeof(TRUSTEE_W));
+
+ if (cCountOfExplicitEntries != 0)
{
- /* free the converted strings */
+ /* calculate the size needed */
+ Size = cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W);
for (i = 0; i != cCountOfExplicitEntries; i++)
{
- if (ListOfExplicitEntriesW[i].Trustee.TrusteeForm == TRUSTEE_IS_NAME)
+ TrusteeForm = GetTrusteeForm(&pListOfExplicitEntriesA[i].Trustee);
+
+ switch (TrusteeForm)
{
- HeapFree(GetProcessHeap(),
- 0,
- ListOfExplicitEntriesW[i].Trustee.ptstrName);
+ case TRUSTEE_IS_NAME:
+ {
+ lpStr = GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
+ if (lpStr != NULL)
+ Size += (strlen(lpStr) + 1) * sizeof(WCHAR);
+ break;
+ }
+
+ case TRUSTEE_IS_OBJECTS_AND_NAME:
+ {
+ POBJECTS_AND_NAME_A oan = (POBJECTS_AND_NAME_A)GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
+
+ if ((oan->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
+ oan->InheritedObjectTypeName != NULL)
+ {
+ Size += (strlen(oan->InheritedObjectTypeName) + 1) * sizeof(WCHAR);
+ }
+
+ if (oan->ptstrName != NULL)
+ Size += (strlen(oan->ptstrName) + 1) * sizeof(WCHAR);
+
+ ObjectsAndNameCount++;
+ break;
+ }
+
+ default:
+ break;
}
}
+ /* allocate the array */
+ peaw = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ Size);
+ if (peaw != NULL)
+ {
+ INT BufferSize;
+ POBJECTS_AND_NAME_W oan = (POBJECTS_AND_NAME_W)(peaw + cCountOfExplicitEntries);
+ LPWSTR StrBuf = (LPWSTR)(oan + ObjectsAndNameCount);
+
+ /* convert the array to unicode */
+ for (i = 0; i != cCountOfExplicitEntries; i++)
+ {
+ peaw[i].grfAccessPermissions = pListOfExplicitEntriesA[i].grfAccessPermissions;
+ peaw[i].grfAccessMode = pListOfExplicitEntriesA[i].grfAccessMode;
+ peaw[i].grfInheritance = pListOfExplicitEntriesA[i].grfInheritance;
+
+ /* convert or copy the TRUSTEE structure */
+ TrusteeForm = GetTrusteeForm(&pListOfExplicitEntriesA[i].Trustee);
+ switch (TrusteeForm)
+ {
+ case TRUSTEE_IS_NAME:
+ {
+ lpStr = GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
+ if (lpStr != NULL)
+ {
+ /* convert the trustee name */
+ BufferSize = strlen(lpStr) + 1;
+
+ if (MultiByteToWideChar(CP_ACP,
+ 0,
+ lpStr,
+ -1,
+ StrBuf,
+ BufferSize) == 0)
+ {
+ goto ConvertErr;
+ }
+ peaw[i].Trustee.ptstrName = StrBuf;
+
+ StrBuf += BufferSize;
+ }
+ else
+ goto RawTrusteeCopy;
+
+ break;
+ }
+
+ case TRUSTEE_IS_OBJECTS_AND_NAME:
+ {
+ POBJECTS_AND_NAME_A oanA = (POBJECTS_AND_NAME_A)GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
+
+ /* copy over the parts of the TRUSTEE structure that don't need
+ to be touched */
+ RtlCopyMemory(&peaw[i].Trustee,
+ &pListOfExplicitEntriesA[i].Trustee,
+ FIELD_OFFSET(TRUSTEE_A,
+ ptstrName));
+
+ peaw[i].Trustee.ptstrName = (LPWSTR)oan;
+
+ /* convert the OBJECTS_AND_NAME_A structure */
+ oan->ObjectsPresent = oanA->ObjectsPresent;
+ oan->ObjectType = oanA->ObjectType;
+
+ if ((oanA->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
+ oanA->InheritedObjectTypeName != NULL)
+ {
+ /* convert inherited object type name */
+ BufferSize = strlen(oanA->InheritedObjectTypeName) + 1;
+
+ if (MultiByteToWideChar(CP_ACP,
+ 0,
+ oanA->InheritedObjectTypeName,
+ -1,
+ StrBuf,
+ BufferSize) == 0)
+ {
+ goto ConvertErr;
+ }
+ oan->InheritedObjectTypeName = StrBuf;
+
+ StrBuf += BufferSize;
+ }
+ else
+ oan->InheritedObjectTypeName = NULL;
+
+ if (oanA->ptstrName != NULL)
+ {
+ /* convert the trustee name */
+ BufferSize = strlen(oanA->ptstrName) + 1;
+
+ if (MultiByteToWideChar(CP_ACP,
+ 0,
+ oanA->ptstrName,
+ -1,
+ StrBuf,
+ BufferSize) == 0)
+ {
+ConvertErr:
+ ErrorCode = GetLastError();
+
+ /* cleanup */
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ peaw);
+
+ return ErrorCode;
+ }
+ oan->ptstrName = StrBuf;
+
+ StrBuf += BufferSize;
+ }
+ else
+ oan->ptstrName = NULL;
+
+ /* move on to the next OBJECTS_AND_NAME_A structure */
+ oan++;
+ break;
+ }
+
+ default:
+ {
+RawTrusteeCopy:
+ /* just copy over the TRUSTEE structure, they don't contain any
+ ansi/unicode specific data */
+ RtlCopyMemory(&peaw[i].Trustee,
+ &pListOfExplicitEntriesA[i].Trustee,
+ sizeof(TRUSTEE_A));
+ break;
+ }
+ }
+ }
+
+ ASSERT(ErrorCode == ERROR_SUCCESS);
+ *pListOfExplicitEntriesW = peaw;
+ }
+ else
+ ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ return ErrorCode;
+}
+
+
+/*
+ * @implemented
+ */
+DWORD
+STDCALL
+SetEntriesInAclA(
+ ULONG cCountOfExplicitEntries,
+ PEXPLICIT_ACCESS_A pListOfExplicitEntries,
+ PACL OldAcl,
+ PACL* NewAcl)
+{
+ PEXPLICIT_ACCESS_W ListOfExplicitEntriesW = NULL;
+ DWORD ErrorCode;
+
+ ErrorCode = InternalExplicitAccessAToW(cCountOfExplicitEntries,
+ pListOfExplicitEntries,
+ &ListOfExplicitEntriesW);
+
+ if (ErrorCode == ERROR_SUCCESS)
+ {
+ ErrorCode = SetEntriesInAclW(cCountOfExplicitEntries,
+ ListOfExplicitEntriesW,
+ OldAcl,
+ NewAcl);
+
/* free the allocated array */
- HeapFree(GetProcessHeap(),
- 0,
- ListOfExplicitEntriesW);
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ ListOfExplicitEntriesW);
}
return ErrorCode;
/*
- * @unimplemented
+ * @implemented
*/
DWORD
STDCALL
IN PTRUSTEE_A pTrustee,
OUT PACCESS_MASK pAccessRights)
{
- DPRINT1("%s() not implemented!\n", __FUNCTION__);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ PTRUSTEE_W pTrusteeW = NULL;
+ DWORD ErrorCode;
+
+ ErrorCode = InternalTrusteeAToW(pTrustee,
+ &pTrusteeW);
+ if (ErrorCode == ERROR_SUCCESS)
+ {
+ ErrorCode = GetEffectiveRightsFromAclW(pacl,
+ pTrusteeW,
+ pAccessRights);
+
+ InternalFreeConvertedTrustee(pTrusteeW,
+ pTrustee);
+ }
+ else
+ ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+
+ return ErrorCode;
}
/*
- * @unimplemented
+ * @implemented
*/
DWORD
STDCALL
OUT PACCESS_MASK pSuccessfulAuditedRights,
OUT PACCESS_MASK pFailedAuditRights)
{
- DPRINT1("%s() not implemented!\n", __FUNCTION__);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ PTRUSTEE_W pTrusteeW = NULL;
+ DWORD ErrorCode;
+
+ ErrorCode = InternalTrusteeAToW(pTrustee,
+ &pTrusteeW);
+ if (ErrorCode == ERROR_SUCCESS)
+ {
+ ErrorCode = GetAuditedPermissionsFromAclW(pacl,
+ pTrusteeW,
+ pSuccessfulAuditedRights,
+ pFailedAuditRights);
+
+ InternalFreeConvertedTrustee(pTrusteeW,
+ pTrustee);
+ }
+ else
+ ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+
+ return ErrorCode;
}
/* EOF */