ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

token.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS system libraries
00004  * FILE:            lib/advapi32/token/token.c
00005  * PURPOSE:         Token functions
00006  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
00007  * UPDATE HISTORY:
00008  *                  Created 01/11/98
00009  */
00010 
00011 #include <advapi32.h>
00012 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
00013 
00014 /*
00015  * @implemented
00016  */
00017 BOOL WINAPI
00018 AdjustTokenGroups(HANDLE TokenHandle,
00019                   BOOL ResetToDefault,
00020                   PTOKEN_GROUPS NewState,
00021                   DWORD BufferLength,
00022                   PTOKEN_GROUPS PreviousState,
00023                   PDWORD ReturnLength)
00024 {
00025     NTSTATUS Status;
00026 
00027     Status = NtAdjustGroupsToken(TokenHandle,
00028                                  ResetToDefault,
00029                                  NewState,
00030                                  BufferLength,
00031                                  PreviousState,
00032                                  (PULONG)ReturnLength);
00033     if (!NT_SUCCESS(Status))
00034     {
00035        SetLastError(RtlNtStatusToDosError(Status));
00036        return FALSE;
00037     }
00038 
00039     return TRUE;
00040 }
00041 
00042 
00043 /*
00044  * @implemented
00045  */
00046 BOOL WINAPI
00047 AdjustTokenPrivileges(HANDLE TokenHandle,
00048                       BOOL DisableAllPrivileges,
00049                       PTOKEN_PRIVILEGES NewState,
00050                       DWORD BufferLength,
00051                       PTOKEN_PRIVILEGES PreviousState,
00052                       PDWORD ReturnLength)
00053 {
00054     NTSTATUS Status;
00055 
00056     Status = NtAdjustPrivilegesToken(TokenHandle,
00057                                      DisableAllPrivileges,
00058                                      NewState,
00059                                      BufferLength,
00060                                      PreviousState,
00061                                      (PULONG)ReturnLength);
00062     if (STATUS_NOT_ALL_ASSIGNED == Status)
00063     {
00064         SetLastError(ERROR_NOT_ALL_ASSIGNED);
00065         return TRUE;
00066     }
00067 
00068     if (!NT_SUCCESS(Status))
00069     {
00070         SetLastError(RtlNtStatusToDosError(Status));
00071         return FALSE;
00072     }
00073 
00074     /* AdjustTokenPrivileges is documented to do this */
00075     SetLastError(ERROR_SUCCESS);
00076 
00077     return TRUE;
00078 }
00079 
00080 
00081 /*
00082  * @implemented
00083  */
00084 BOOL WINAPI
00085 GetTokenInformation(HANDLE TokenHandle,
00086                     TOKEN_INFORMATION_CLASS TokenInformationClass,
00087                     LPVOID TokenInformation,
00088                     DWORD TokenInformationLength,
00089                     PDWORD ReturnLength)
00090 {
00091     NTSTATUS Status;
00092 
00093     Status = NtQueryInformationToken(TokenHandle,
00094                                      TokenInformationClass,
00095                                      TokenInformation,
00096                                      TokenInformationLength,
00097                                      (PULONG)ReturnLength);
00098     if (!NT_SUCCESS(Status))
00099     {
00100         SetLastError(RtlNtStatusToDosError(Status));
00101         return FALSE;
00102     }
00103 
00104   return TRUE;
00105 }
00106 
00107 
00108 /*
00109  * @implemented
00110  */
00111 BOOL WINAPI
00112 SetTokenInformation(HANDLE TokenHandle,
00113                     TOKEN_INFORMATION_CLASS TokenInformationClass,
00114                     LPVOID TokenInformation,
00115                     DWORD TokenInformationLength)
00116 {
00117     NTSTATUS Status;
00118 
00119     Status = NtSetInformationToken(TokenHandle,
00120                                    TokenInformationClass,
00121                                    TokenInformation,
00122                                    TokenInformationLength);
00123     if (!NT_SUCCESS(Status))
00124     {
00125         SetLastError(RtlNtStatusToDosError(Status));
00126         return FALSE;
00127     }
00128 
00129     return TRUE;
00130 }
00131 
00132 
00133 /*
00134  * @implemented
00135  */
00136 BOOL
00137 WINAPI
00138 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
00139             IN HANDLE ClientToken,
00140             IN DWORD DesiredAccess,
00141             IN PGENERIC_MAPPING GenericMapping,
00142             OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL,
00143             IN OUT LPDWORD PrivilegeSetLength,
00144             OUT LPDWORD GrantedAccess,
00145             OUT LPBOOL AccessStatus)
00146 {
00147     NTSTATUS Status;
00148     NTSTATUS NtAccessStatus;
00149 
00150     /* Do the access check */
00151     Status = NtAccessCheck(pSecurityDescriptor,
00152                            ClientToken,
00153                            DesiredAccess,
00154                            GenericMapping,
00155                            PrivilegeSet,
00156                            (PULONG)PrivilegeSetLength,
00157                            (PACCESS_MASK)GrantedAccess,
00158                            &NtAccessStatus);
00159 
00160     /* See if the access check operation succeeded */
00161     if (!NT_SUCCESS(Status))
00162     {
00163         /* Check failed */
00164         SetLastError(RtlNtStatusToDosError(Status));
00165         return FALSE;
00166     }
00167 
00168     /* Now check the access status  */
00169     if (!NT_SUCCESS(NtAccessStatus))
00170     {
00171         /* Access denied */
00172         SetLastError(RtlNtStatusToDosError(NtAccessStatus));
00173         *AccessStatus = FALSE;
00174     }
00175     else
00176     {
00177         /* Access granted */
00178         *AccessStatus = TRUE;
00179     }
00180 
00181     /* Check succeeded */
00182     return TRUE;
00183 }
00184 
00185 /*
00186  * @unimplemented
00187  */
00188 BOOL WINAPI AccessCheckByType(
00189     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
00190     PSID PrincipalSelfSid,
00191     HANDLE ClientToken, 
00192     DWORD DesiredAccess, 
00193     POBJECT_TYPE_LIST ObjectTypeList,
00194     DWORD ObjectTypeListLength,
00195     PGENERIC_MAPPING GenericMapping,
00196     PPRIVILEGE_SET PrivilegeSet,
00197     LPDWORD PrivilegeSetLength, 
00198     LPDWORD GrantedAccess,
00199     LPBOOL AccessStatus)
00200 {
00201     FIXME("stub\n");
00202 
00203     *AccessStatus = TRUE;
00204 
00205     return !*AccessStatus;
00206 }
00207 
00208 /*
00209  * @implemented
00210  */
00211 BOOL WINAPI
00212 OpenProcessToken(HANDLE ProcessHandle,
00213                  DWORD DesiredAccess,
00214                  PHANDLE TokenHandle)
00215 {
00216     NTSTATUS Status;
00217 
00218     Status = NtOpenProcessToken(ProcessHandle,
00219                                 DesiredAccess,
00220                                 TokenHandle);
00221     if (!NT_SUCCESS(Status))
00222     {
00223         SetLastError(RtlNtStatusToDosError(Status));
00224         return FALSE;
00225     }
00226 
00227     return TRUE;
00228 }
00229 
00230 
00231 /*
00232  * @implemented
00233  */
00234 BOOL WINAPI
00235 OpenThreadToken(HANDLE ThreadHandle,
00236                 DWORD DesiredAccess,
00237                 BOOL OpenAsSelf,
00238                 PHANDLE TokenHandle)
00239 {
00240     NTSTATUS Status;
00241 
00242     Status = NtOpenThreadToken(ThreadHandle,
00243                                DesiredAccess,
00244                                OpenAsSelf,
00245                                TokenHandle);
00246     if (!NT_SUCCESS(Status))
00247     {
00248         SetLastError(RtlNtStatusToDosError(Status));
00249         return FALSE;
00250     }
00251 
00252     return TRUE;
00253 }
00254 
00255 
00256 /*
00257  * @implemented
00258  */
00259 BOOL WINAPI
00260 SetThreadToken(IN PHANDLE ThreadHandle  OPTIONAL,
00261                IN HANDLE TokenHandle)
00262 {
00263     NTSTATUS Status;
00264     HANDLE hThread;
00265 
00266     hThread = (ThreadHandle != NULL) ? *ThreadHandle : NtCurrentThread();
00267 
00268     Status = NtSetInformationThread(hThread,
00269                                     ThreadImpersonationToken,
00270                                     &TokenHandle,
00271                                     sizeof(HANDLE));
00272     if (!NT_SUCCESS(Status))
00273     {
00274         SetLastError(RtlNtStatusToDosError(Status));
00275         return FALSE;
00276     }
00277 
00278     return TRUE;
00279 }
00280 
00281 
00282 /*
00283  * @implemented
00284  */
00285 BOOL WINAPI
00286 DuplicateTokenEx(IN HANDLE ExistingTokenHandle,
00287                  IN DWORD dwDesiredAccess,
00288                  IN LPSECURITY_ATTRIBUTES lpTokenAttributes  OPTIONAL,
00289                  IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
00290                  IN TOKEN_TYPE TokenType,
00291                  OUT PHANDLE DuplicateTokenHandle)
00292 {
00293     OBJECT_ATTRIBUTES ObjectAttributes;
00294     NTSTATUS Status;
00295     SECURITY_QUALITY_OF_SERVICE Sqos;
00296 
00297     Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
00298     Sqos.ImpersonationLevel = ImpersonationLevel;
00299     Sqos.ContextTrackingMode = 0;
00300     Sqos.EffectiveOnly = FALSE;
00301 
00302     if (lpTokenAttributes != NULL)
00303     {
00304         InitializeObjectAttributes(&ObjectAttributes,
00305                                    NULL,
00306                                    lpTokenAttributes->bInheritHandle ? OBJ_INHERIT : 0,
00307                                    NULL,
00308                                    lpTokenAttributes->lpSecurityDescriptor);
00309     }
00310     else
00311     {
00312         InitializeObjectAttributes(&ObjectAttributes,
00313                                    NULL,
00314                                    0,
00315                                    NULL,
00316                                    NULL);
00317     }
00318 
00319     ObjectAttributes.SecurityQualityOfService = &Sqos;
00320 
00321     Status = NtDuplicateToken(ExistingTokenHandle,
00322                               dwDesiredAccess,
00323                               &ObjectAttributes,
00324                               FALSE,
00325                               TokenType,
00326                               DuplicateTokenHandle);
00327     if (!NT_SUCCESS(Status))
00328     {
00329         SetLastError(RtlNtStatusToDosError(Status));
00330         return FALSE;
00331     }
00332 
00333     return TRUE;
00334 }
00335 
00336 
00337 /*
00338  * @implemented
00339  */
00340 BOOL WINAPI
00341 DuplicateToken(IN HANDLE ExistingTokenHandle,
00342                IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
00343                OUT PHANDLE DuplicateTokenHandle)
00344 {
00345     return DuplicateTokenEx(ExistingTokenHandle,
00346                             TOKEN_IMPERSONATE | TOKEN_QUERY,
00347                             NULL,
00348                             ImpersonationLevel,
00349                             TokenImpersonation,
00350                             DuplicateTokenHandle);
00351 }
00352 
00353 
00354 /*
00355  * @implemented
00356  */
00357 BOOL WINAPI
00358 CheckTokenMembership(IN HANDLE ExistingTokenHandle,
00359                      IN PSID SidToCheck,
00360                      OUT PBOOL IsMember)
00361 {
00362     PISECURITY_DESCRIPTOR SecurityDescriptor = NULL;
00363     ACCESS_MASK GrantedAccess;
00364     struct
00365     {
00366         PRIVILEGE_SET PrivilegeSet;
00367         LUID_AND_ATTRIBUTES Privileges[4];
00368     } PrivBuffer;
00369     ULONG PrivBufferSize = sizeof(PrivBuffer);
00370     GENERIC_MAPPING GenericMapping =
00371     {
00372         STANDARD_RIGHTS_READ,
00373         STANDARD_RIGHTS_WRITE,
00374         STANDARD_RIGHTS_EXECUTE,
00375         STANDARD_RIGHTS_ALL
00376     };
00377     PACL Dacl;
00378     ULONG SidLen;
00379     HANDLE hToken = NULL;
00380     NTSTATUS Status, AccessStatus;
00381 
00382     /* doesn't return gracefully if IsMember is NULL! */
00383     *IsMember = FALSE;
00384 
00385     SidLen = RtlLengthSid(SidToCheck);
00386 
00387     if (ExistingTokenHandle == NULL)
00388     {
00389         Status = NtOpenThreadToken(NtCurrentThread(),
00390                                    TOKEN_QUERY,
00391                                    FALSE,
00392                                    &hToken);
00393 
00394         if (Status == STATUS_NO_TOKEN)
00395         {
00396             /* we're not impersonating, open the primary token */
00397             Status = NtOpenProcessToken(NtCurrentProcess(),
00398                                         TOKEN_QUERY | TOKEN_DUPLICATE,
00399                                         &hToken);
00400             if (NT_SUCCESS(Status))
00401             {
00402                 HANDLE hNewToken = FALSE;
00403                 BOOL DupRet;
00404 
00405                 /* duplicate the primary token to create an impersonation token */
00406                 DupRet = DuplicateTokenEx(hToken,
00407                                           TOKEN_QUERY | TOKEN_IMPERSONATE,
00408                                           NULL,
00409                                           SecurityImpersonation,
00410                                           TokenImpersonation,
00411                                           &hNewToken);
00412 
00413                 NtClose(hToken);
00414 
00415                 if (!DupRet)
00416                 {
00417                     WARN("Failed to duplicate the primary token!\n");
00418                     return FALSE;
00419                 }
00420 
00421                 hToken = hNewToken;
00422             }
00423         }
00424 
00425         if (!NT_SUCCESS(Status))
00426         {
00427             goto Cleanup;
00428         }
00429     }
00430     else
00431     {
00432         hToken = ExistingTokenHandle;
00433     }
00434 
00435     /* create a security descriptor */
00436     SecurityDescriptor = RtlAllocateHeap(RtlGetProcessHeap(),
00437                                          0,
00438                                          sizeof(SECURITY_DESCRIPTOR) +
00439                                              sizeof(ACL) + SidLen +
00440                                              sizeof(ACCESS_ALLOWED_ACE));
00441     if (SecurityDescriptor == NULL)
00442     {
00443         Status = STATUS_INSUFFICIENT_RESOURCES;
00444         goto Cleanup;
00445     }
00446 
00447     Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
00448                                          SECURITY_DESCRIPTOR_REVISION);
00449     if (!NT_SUCCESS(Status))
00450     {
00451         goto Cleanup;
00452     }
00453 
00454     /* set the owner and group */
00455     Status = RtlSetOwnerSecurityDescriptor(SecurityDescriptor,
00456                                            SidToCheck,
00457                                            FALSE);
00458     if (!NT_SUCCESS(Status))
00459     {
00460         goto Cleanup;
00461     }
00462 
00463     Status = RtlSetGroupSecurityDescriptor(SecurityDescriptor,
00464                                            SidToCheck,
00465                                            FALSE);
00466     if (!NT_SUCCESS(Status))
00467     {
00468         goto Cleanup;
00469     }
00470 
00471     /* create the DACL */
00472     Dacl = (PACL)(SecurityDescriptor + 1);
00473     Status = RtlCreateAcl(Dacl,
00474                           sizeof(ACL) + SidLen + sizeof(ACCESS_ALLOWED_ACE),
00475                           ACL_REVISION);
00476     if (!NT_SUCCESS(Status))
00477     {
00478         goto Cleanup;
00479     }
00480 
00481     Status = RtlAddAccessAllowedAce(Dacl,
00482                                     ACL_REVISION,
00483                                     0x1,
00484                                     SidToCheck);
00485     if (!NT_SUCCESS(Status))
00486     {
00487         goto Cleanup;
00488     }
00489 
00490     /* assign the DACL to the security descriptor */
00491     Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
00492                                           TRUE,
00493                                           Dacl,
00494                                           FALSE);
00495     if (!NT_SUCCESS(Status))
00496     {
00497         goto Cleanup;
00498     }
00499 
00500     /* it's time to perform the access check. Just use _some_ desired access right
00501        (same as for the ACE) and see if we're getting it granted. This indicates
00502        our SID is a member of the token. We however can't use a generic access
00503        right as those aren't mapped and return an error (STATUS_GENERIC_NOT_MAPPED). */
00504     Status = NtAccessCheck(SecurityDescriptor,
00505                            hToken,
00506                            0x1,
00507                            &GenericMapping,
00508                            &PrivBuffer.PrivilegeSet,
00509                            &PrivBufferSize,
00510                            &GrantedAccess,
00511                            &AccessStatus);
00512     if (NT_SUCCESS(Status) && NT_SUCCESS(AccessStatus) && (GrantedAccess == 0x1))
00513     {
00514         *IsMember = TRUE;
00515     }
00516 
00517 Cleanup:
00518     if (hToken != NULL && hToken != ExistingTokenHandle)
00519     {
00520         NtClose(hToken);
00521     }
00522 
00523     if (SecurityDescriptor != NULL)
00524     {
00525         RtlFreeHeap(RtlGetProcessHeap(),
00526                     0,
00527                     SecurityDescriptor);
00528     }
00529 
00530     if (!NT_SUCCESS(Status))
00531     {
00532         SetLastError(RtlNtStatusToDosError(Status));
00533         return FALSE;
00534     }
00535 
00536     return TRUE;
00537 }
00538 
00539 
00540 /*
00541  * @implemented
00542  */
00543 BOOL WINAPI
00544 IsTokenRestricted(HANDLE TokenHandle)
00545 {
00546     ULONG RetLength;
00547     PTOKEN_GROUPS lpGroups;
00548     NTSTATUS Status;
00549     BOOL Ret = FALSE;
00550 
00551     /* determine the required buffer size and allocate enough memory to read the
00552        list of restricted SIDs */
00553     Status = NtQueryInformationToken(TokenHandle,
00554                                      TokenRestrictedSids,
00555                                      NULL,
00556                                      0,
00557                                      &RetLength);
00558     if (Status != STATUS_BUFFER_TOO_SMALL)
00559     {
00560         SetLastError(RtlNtStatusToDosError(Status));
00561         return FALSE;
00562     }
00563 
00564 AllocAndReadRestrictedSids:
00565     lpGroups = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
00566                                         0,
00567                                         RetLength);
00568     if (lpGroups == NULL)
00569     {
00570         SetLastError(ERROR_OUTOFMEMORY);
00571         return FALSE;
00572     }
00573 
00574     /* actually read the list of the restricted SIDs */
00575     Status = NtQueryInformationToken(TokenHandle,
00576                                      TokenRestrictedSids,
00577                                      lpGroups,
00578                                      RetLength,
00579                                      &RetLength);
00580     if (NT_SUCCESS(Status))
00581     {
00582         Ret = (lpGroups->GroupCount != 0);
00583     }
00584     else if (Status == STATUS_BUFFER_TOO_SMALL)
00585     {
00586         /* looks like the token was modified in the meanwhile, let's just try again */
00587         HeapFree(GetProcessHeap(),
00588                  0,
00589                  lpGroups);
00590 
00591         goto AllocAndReadRestrictedSids;
00592     }
00593     else
00594     {
00595         SetLastError(RtlNtStatusToDosError(Status));
00596     }
00597 
00598     /* free allocated memory */
00599     HeapFree(GetProcessHeap(),
00600              0,
00601              lpGroups);
00602 
00603     return Ret;
00604 }
00605 
00606 
00607 BOOL WINAPI
00608 CreateRestrictedToken(HANDLE TokenHandle,
00609                       DWORD Flags,
00610                       DWORD DisableSidCount,
00611                       PSID_AND_ATTRIBUTES pSidAndAttributes,
00612                       DWORD DeletePrivilegeCount,
00613                       PLUID_AND_ATTRIBUTES pLUIDAndAttributes,
00614                       DWORD RestrictedSidCount,
00615                       PSID_AND_ATTRIBUTES pSIDAndAttributes,
00616                       PHANDLE NewTokenHandle)
00617 {
00618     UNIMPLEMENTED;
00619     return FALSE;
00620 }
00621 
00622 
00623 /*
00624  * @unimplemented
00625  */
00626 PSID
00627 WINAPI
00628 GetSiteSidFromToken(IN HANDLE TokenHandle)
00629 {
00630     PTOKEN_GROUPS RestrictedSids;
00631     ULONG RetLen;
00632     UINT i;
00633     NTSTATUS Status;
00634     PSID PSiteSid = NULL;
00635     SID_IDENTIFIER_AUTHORITY InternetSiteAuthority = {SECURITY_INTERNETSITE_AUTHORITY};
00636 
00637     Status = NtQueryInformationToken(TokenHandle,
00638                                      TokenRestrictedSids,
00639                                      NULL,
00640                                      0,
00641                                      &RetLen);
00642     if (Status != STATUS_BUFFER_TOO_SMALL)
00643     {
00644         SetLastError(RtlNtStatusToDosError(Status));
00645         return NULL;
00646     }
00647 
00648     RestrictedSids = (PTOKEN_GROUPS)RtlAllocateHeap(RtlGetProcessHeap(),
00649                                                     0,
00650                                                     RetLen);
00651     if (RestrictedSids == NULL)
00652     {
00653         SetLastError(ERROR_OUTOFMEMORY);
00654         return NULL;
00655     }
00656 
00657     Status = NtQueryInformationToken(TokenHandle,
00658                                      TokenRestrictedSids,
00659                                      RestrictedSids,
00660                                      RetLen,
00661                                      &RetLen);
00662     if (NT_SUCCESS(Status))
00663     {
00664         for (i = 0; i < RestrictedSids->GroupCount; i++)
00665         {
00666             SID* RSSid = RestrictedSids->Groups[i].Sid;
00667 
00668             if (RtlCompareMemory(&(RSSid->IdentifierAuthority),
00669                                  &InternetSiteAuthority,
00670                                  sizeof(SID_IDENTIFIER_AUTHORITY)) ==
00671                                  sizeof(SID_IDENTIFIER_AUTHORITY))
00672             {
00673                 PSiteSid = RtlAllocateHeap(RtlGetProcessHeap(),
00674                                            0,
00675                                            RtlLengthSid((RestrictedSids->
00676                                                          Groups[i]).Sid));
00677                 if (PSiteSid == NULL)
00678                 {
00679                     SetLastError(ERROR_OUTOFMEMORY);
00680                 }
00681                 else
00682                 {
00683                     RtlCopySid(RtlLengthSid(RestrictedSids->Groups[i].Sid),
00684                                PSiteSid,
00685                                RestrictedSids->Groups[i].Sid);
00686                 }
00687 
00688                 break;
00689             }
00690         }
00691     }
00692     else
00693     {
00694         SetLastError(RtlNtStatusToDosError(Status));
00695     }
00696 
00697     RtlFreeHeap(RtlGetProcessHeap(), 0, RestrictedSids);
00698     return PSiteSid;
00699 }
00700 
00701 
00702 BOOL
00703 WINAPI
00704 CreateProcessWithTokenW(IN HANDLE hToken,
00705                         IN DWORD dwLogonFlags,
00706                         IN LPCWSTR lpApplicationName OPTIONAL,
00707                         IN OUT LPWSTR lpCommandLine OPTIONAL,
00708                         IN DWORD dwCreationFlags,
00709                         IN LPVOID lpEnvironment OPTIONAL,
00710                         IN LPCWSTR lpCurrentDirectory OPTIONAL,
00711                         IN LPSTARTUPINFOW lpStartupInfo,
00712                         OUT LPPROCESS_INFORMATION lpProcessInfo)
00713 {
00714     UNIMPLEMENTED;
00715     return FALSE;
00716 }

Generated on Sat May 26 2012 04:21:14 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.