Ejemplo n.º 1
0
VOID
FinishBenchMark (
    IN PPERFINFO PerfInfo
    )

{

    ULONG ContextSwitches;
    LARGE_INTEGER Duration;
    ULONG FirstLevelFills;
    ULONG InterruptCount;
    ULONG Length;
    ULONG Performance;
    ULONG SecondLevelFills;
    NTSTATUS Status;
    ULONG SystemCalls;
    SYSTEM_PERFORMANCE_INFORMATION SystemInfo;


    //
    // Print results and announce end of test.
    //

    NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StopTime);

    Duration.QuadPart = PerfInfo->StopTime.QuadPart - PerfInfo->StartTime.QuadPart;
    Length = Duration.LowPart / 10000;
    printf("%d (%s)\n", Length,PerfInfo->Title);
    return;
}
Ejemplo n.º 2
0
static int l_gettime(lua_State *L)
{
#if 0
    union {
        FILETIME ft;
        ULONGLONG ull;
    } u = {0};
    const double scale = 1.0e9;
    GetSystemTimePreciseAsFileTime(&u.ft);
#elif 0
    union {
        LARGE_INTEGER li;
        ULONGLONG ull;
    } u = {0};
    const double scale = 1.0e7;
    NtQuerySystemTime(&u.li);
#else
    union {
        FILETIME ft;
        ULONGLONG ull;
    } u = {0};
    const double scale = 1.0e7;

    SYSTEMTIME st = {0};
    GetSystemTime(&st);
    SystemTimeToFileTime(&st, &u.ft);

#endif

    const double win32Epoch = ((double)u.ull)/scale;
    const double unixEpoch = win32Epoch - SEC_TO_UNIX_EPOCH;

    lua_pushnumber(L, (lua_Number)(unixEpoch));
    return 1;
}
Ejemplo n.º 3
0
bool create_bad_block_inode( PEXT2_FILESYS Ext2Sys,
                             PEXT2_BADBLK_LIST bb_list)
{
    bool            retval;
    EXT2_INODE      inode;
    LARGE_INTEGER   SysTime;
    
    NtQuerySystemTime(&SysTime);

    ext2_mark_inode_bitmap(Ext2Sys->inode_map, EXT2_BAD_INO);

    Ext2Sys->group_desc[0].bg_free_inodes_count--;
    Ext2Sys->ext2_sb->s_free_inodes_count--;

    memset(&inode, 0, sizeof(EXT2_INODE));
    inode.i_mode = (USHORT)((0777 & ~Ext2Sys->umask));
    inode.i_uid = inode.i_gid = 0;
    inode.i_blocks = 0;
    inode.i_block[0] = 0;
    inode.i_links_count = 2;
    RtlTimeToSecondsSince1970(&SysTime, &inode.i_mtime);
    inode.i_ctime = inode.i_atime = inode.i_mtime;
    inode.i_size = 0;

    retval = ext2_save_inode(Ext2Sys, EXT2_BAD_INO, &inode);

    return retval;
}
Ejemplo n.º 4
0
VOID
LogfReportEvent(USHORT wType,
                USHORT wCategory,
                ULONG  dwEventId,
                USHORT wNumStrings,
                PWSTR  pStrings,
                ULONG  dwDataSize,
                PVOID  pRawData)
{
    NTSTATUS Status;
    UNICODE_STRING SourceName, ComputerName;
    PEVENTLOGRECORD LogBuffer;
    LARGE_INTEGER SystemTime;
    ULONG Time;
    SIZE_T RecSize;
    DWORD dwComputerNameLength;
    WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];

    if (!EventLogSource)
        return;

    RtlInitUnicodeString(&SourceName, EventLogSource->szName);

    dwComputerNameLength = ARRAYSIZE(szComputerName);
    if (!GetComputerNameW(szComputerName, &dwComputerNameLength))
        szComputerName[0] = L'\0';

    RtlInitUnicodeString(&ComputerName, szComputerName);

    NtQuerySystemTime(&SystemTime);
    RtlTimeToSecondsSince1970(&SystemTime, &Time);

    LogBuffer = LogfAllocAndBuildNewRecord(&RecSize,
                                           Time,
                                           wType,
                                           wCategory,
                                           dwEventId,
                                           &SourceName,
                                           &ComputerName,
                                           0,
                                           NULL,
                                           wNumStrings,
                                           pStrings,
                                           dwDataSize,
                                           pRawData);
    if (LogBuffer == NULL)
    {
        DPRINT1("LogfAllocAndBuildNewRecord failed!\n");
        return;
    }

    Status = LogfWriteRecord(EventLogSource->LogFile, LogBuffer, RecSize);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n",
                EventLogSource->LogFile->LogName, Status);
    }

    LogfFreeRecord(LogBuffer);
}
Ejemplo n.º 5
0
/******************************************************************************
 * NtGetTickCount   (NTDLL.@)
 * ZwGetTickCount   (NTDLL.@)
 */
ULONG WINAPI NtGetTickCount(void)
{
    LARGE_INTEGER now;

    NtQuerySystemTime( &now );
    return (now.QuadPart - server_start_time) / 10000;
}
Ejemplo n.º 6
0
VOID NTAPI
RtlRunEncodeUnicodeString (IN OUT PUCHAR Hash,
                           IN OUT PUNICODE_STRING String)
{
   LARGE_INTEGER CurrentTime;
   PUCHAR ptr;
   USHORT i;
   NTSTATUS Status;

   ptr = (PUCHAR) String->Buffer;
   if (*Hash == 0)
   {
      Status = NtQuerySystemTime (&CurrentTime);
      if (NT_SUCCESS(Status))
      {
         for (i = 1; i < sizeof(LARGE_INTEGER) && (*Hash == 0); i++)
            *Hash |= *(PUCHAR)(((PUCHAR)&CurrentTime) + i);
      }

      if (*Hash == 0)
         *Hash = 1;
   }

   if (String->Length >= 1)
   {
      ptr[0] ^= (*Hash) | (UCHAR)0x43;
      if (String->Length > 1)
      {
         for (i = 1; i < String->Length; i++)
         {
            ptr[i] ^= ptr[i - 1] ^ (*Hash);
         }
      }
   }
}
Ejemplo n.º 7
0
time_t
time_now(
    VOID
    )
/*++

Routine Description:

    This function returns the UTC time in seconds since 1970.

Arguments:

    None.

Return Value:

    None.

--*/
{

   LARGE_INTEGER Time;
   time_t CurrentTime;

   // Get the 64-bit system time.
   // Convert the system time to the number of seconds
   // since 1-1-1970.
   //

   NtQuerySystemTime(&Time);
   RtlTimeToSecondsSince1970(&Time, (PVOID) &CurrentTime);
   return(CurrentTime);

}
Ejemplo n.º 8
0
/***********************************************************************
 *              GetSystemTimeAsFileTime  (KERNEL32.@)
 *
 *  Get the current time in utc format.
 *
 *  RETURNS
 *   Nothing.
 */
VOID WINAPI GetSystemTimeAsFileTime(
    LPFILETIME time) /* [out] Destination for the current utc time */
{
    LARGE_INTEGER t;
    NtQuerySystemTime( &t );
    time->dwLowDateTime = t.u.LowPart;
    time->dwHighDateTime = t.u.HighPart;
}
Ejemplo n.º 9
0
VOID
FinishBenchMark (
    IN PPERFINFO PerfInfo
    )

{

    ULONG ContextSwitches;
    LARGE_INTEGER Duration;
    ULONG FirstLevelFills;
    ULONG InterruptCount;
    ULONG Length;
    ULONG Performance;
    ULONG SecondLevelFills;
    NTSTATUS Status;
    ULONG SystemCalls;
    SYSTEM_PERFORMANCE_INFORMATION SystemInfo;


    //
    // Print results and announce end of test.
    //

    NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StopTime);
    Status = NtQuerySystemInformation(SystemPerformanceInformation,
                                      (PVOID)&SystemInfo,
                                      sizeof(SYSTEM_PERFORMANCE_INFORMATION),
                                      NULL);

    if (NT_SUCCESS(Status) == FALSE) {
        printf("Failed to query performance information, status = %lx\n", Status);
        return;
    }

    Duration = RtlLargeIntegerSubtract(PerfInfo->StopTime, PerfInfo->StartTime);
    Length = Duration.LowPart / 10000;
    printf("        Test time in milliseconds %d\n", Length);
    printf("        Number of iterations      %d\n", PerfInfo->Iterations);

    Performance = PerfInfo->Iterations * 1000 / Length;
    printf("        Iterations per second     %d\n", Performance);

    ContextSwitches = SystemInfo.ContextSwitches - PerfInfo->ContextSwitches;
    FirstLevelFills = SystemInfo.FirstLevelTbFills - PerfInfo->FirstLevelFills;
    InterruptCount = SystemInfo.InterruptCount - PerfInfo->InterruptCount;
    SecondLevelFills = SystemInfo.SecondLevelTbFills - PerfInfo->SecondLevelFills;
    SystemCalls = SystemInfo.SystemCalls - PerfInfo->SystemCalls;
    printf("        First Level TB Fills      %d\n", FirstLevelFills);
    printf("        Second Level TB Fills     %d\n", SecondLevelFills);
    printf("        Number of Interrupts      %d\n", InterruptCount);
    printf("        Total Context Switches    %d\n", ContextSwitches);
    printf("        Number of System Calls    %d\n", SystemCalls);

    printf("*** End of Test ***\n\n");
    return;
}
Ejemplo n.º 10
0
/*********************************************************************
 *      GetSystemTime                                   (KERNEL32.@)
 *
 * Get the current system time.
 *
 * PARAMS
 *  systime [O] Destination for current time.
 *
 * RETURNS
 *  Nothing.
 */
VOID WINAPI GetSystemTime(LPSYSTEMTIME systime)
{
    FILETIME ft;
    LARGE_INTEGER t;

    NtQuerySystemTime(&t);
    ft.dwLowDateTime = t.u.LowPart;
    ft.dwHighDateTime = t.u.HighPart;
    FileTimeToSystemTime(&ft, systime);
}
Ejemplo n.º 11
0
/*********************************************************************
 *      GetSystemTime                                   (KERNEL32.@)
 *
 * Get the current system time.
 *
 * RETURNS
 *  Nothing.
 */
VOID WINAPI GetSystemTime(LPSYSTEMTIME systime) /* [O] Destination for current time */
{
  FILETIME ft;
  LARGE_INTEGER t;

  TRACEN((printf("GetSystemTime\n")))
  NtQuerySystemTime(&t);
  ft.dwLowDateTime = (DWORD)(t.QuadPart);
  ft.dwHighDateTime = (DWORD)(t.QuadPart >> 32);
  FileTimeToSystemTime(&ft, systime);
}
Ejemplo n.º 12
0
/*********************************************************************
 *      GetLocalTime                                    (KERNEL32.@)
 *
 * Get the current local time.
 *
 * PARAMS
 *  systime [O] Destination for current time.
 *
 * RETURNS
 *  Nothing.
 */
VOID WINAPI GetLocalTime(LPSYSTEMTIME systime)
{
    FILETIME lft;
    LARGE_INTEGER ft, ft2;

    NtQuerySystemTime(&ft);
    RtlSystemTimeToLocalTime(&ft, &ft2);
    lft.dwLowDateTime = ft2.u.LowPart;
    lft.dwHighDateTime = ft2.u.HighPart;
    FileTimeToSystemTime(&lft, systime);
}
Ejemplo n.º 13
0
/**************************************************************************
 *  __wine_user_shared_data   (NTDLL.@)
 *
 * Update user shared data and return the address of the structure.
 */
BYTE* CDECL __wine_user_shared_data(void)
{
    LARGE_INTEGER now;
    NtQuerySystemTime( &now );
    user_shared_data->SystemTime.LowPart = now.u.LowPart;
    user_shared_data->SystemTime.High1Time = user_shared_data->SystemTime.High2Time = now.u.HighPart;
    user_shared_data->u.TickCountQuad = (now.QuadPart - server_start_time) / 10000;
    user_shared_data->u.TickCount.High2Time = user_shared_data->u.TickCount.High1Time;
    user_shared_data->TickCountLowDeprecated = user_shared_data->u.TickCount.LowPart;
    user_shared_data->TickCountMultiplier = 1 << 24;
    return (BYTE *)user_shared_data;
}
Ejemplo n.º 14
0
/******************************************************************************
 *  NtQueryPerformanceCounter	[NTDLL.@]
 *
 *  Note: Windows uses a timer clocked at a multiple of 1193182 Hz. There is a
 *  good number of applications that crash when the returned frequency is either
 *  lower or higher than what Windows gives. Also too high counter values are
 *  reported to give problems.
 */
NTSTATUS WINAPI NtQueryPerformanceCounter( PLARGE_INTEGER Counter, PLARGE_INTEGER Frequency )
{
    LARGE_INTEGER now;

    if (!Counter) return STATUS_ACCESS_VIOLATION;

    /* convert a counter that increments at a rate of 10 MHz
     * to one of 1.193182 MHz, with some care for arithmetic
     * overflow and good accuracy (21/176 = 0.11931818) */
    NtQuerySystemTime( &now );
    Counter->QuadPart = ((now.QuadPart - server_start_time) * 21) / 176;
    if (Frequency) Frequency->QuadPart = 1193182;
    return STATUS_SUCCESS;
}
Ejemplo n.º 15
0
static ULONG
CalcVolumeSerialNumber(VOID)
{
    LARGE_INTEGER SystemTime;
    TIME_FIELDS TimeFields;
    ULONG Serial;
    PUCHAR Buffer;

    NtQuerySystemTime (&SystemTime);
    RtlTimeToTimeFields (&SystemTime, &TimeFields);

    Buffer = (PUCHAR)&Serial;
    Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
    Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
    Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
    Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);

    return Serial;
}
Ejemplo n.º 16
0
static NTSTATUS
LsapCreateRandomDomainSid(OUT PSID *Sid)
{
    LARGE_INTEGER SystemTime;
    PULONG Seed;

    NtQuerySystemTime(&SystemTime);
    Seed = &SystemTime.u.LowPart;

    return RtlAllocateAndInitializeSid(&NtAuthority,
                                       4,
                                       SECURITY_NT_NON_UNIQUE,
                                       RtlUniform(Seed),
                                       RtlUniform(Seed),
                                       RtlUniform(Seed),
                                       SECURITY_NULL_RID,
                                       SECURITY_NULL_RID,
                                       SECURITY_NULL_RID,
                                       SECURITY_NULL_RID,
                                       Sid);
}
Ejemplo n.º 17
0
VOID
StartBenchMark (
    IN PCHAR Title,
    IN ULONG Iterations,
    IN PPERFINFO PerfInfo
    )

{

    NTSTATUS Status;
    SYSTEM_PERFORMANCE_INFORMATION SystemInfo;

    //
    // Announce start of test and the number of iterations.
    //

    PerfInfo->Title = Title;
    PerfInfo->Iterations = Iterations;
    NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StartTime);
    return;
}
Ejemplo n.º 18
0
int main()
{
	wcscpy(path+4,GetModulePath());
	LPWSTR p=path;
	while (*p) p++;
	while (*p!=L'\\') p--;
	p--;
	while (*p!=L'\\') p--;
	p++;
	wcscpy(p,L"version.h");
	UNICODE_STRING us;
	RtlInitUnicodeString(&us,path);
	OBJECT_ATTRIBUTES oa={sizeof(oa),0,&us,OBJ_CASE_INSENSITIVE,0,0};
	HANDLE hFile;
	IO_STATUS_BLOCK isb;
	if (!NT_SUCCESS(NtCreateFile(&hFile,
		FILE_SHARE_READ|FILE_WRITE_DATA|FILE_READ_ATTRIBUTES|SYNCHRONIZE
		,&oa,&isb,0,0,FILE_SHARE_READ,FILE_OPEN_IF,
		FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE,0,0)))
		return 1;
	FILE_BASIC_INFORMATION basic;
	NtQueryInformationFile(hFile,&isb,&basic,sizeof(basic),FileBasicInformation);
	
	int l=strlen(buffer);
	char* ptr;
	ptr=buffer+l;
	LARGE_INTEGER current_time;
	TIME_FIELDS tf,ctf;
	NtQuerySystemTime(&current_time);
	current_time.QuadPart-=GetTimeBias()->QuadPart;
	RtlTimeToTimeFields(&current_time,&tf);
	RtlTimeToTimeFields(&basic.LastWriteTime,&ctf);
	if (ctf.wDay!=tf.wDay||ctf.wMonth!=tf.wMonth||ctf.wYear!=tf.wYear){
		l+=sprintf(ptr,"%.4d.%.2d.%.2d)\\r\\n\";",tf.wYear,tf.wMonth,tf.wDay);
		NtWriteFile(hFile,0,0,0,&isb,buffer,l,0,0);
	}
	NtClose(hFile);
	return 0;
	//IthCloseSystemService();
}
Ejemplo n.º 19
0
VOID
StartBenchMark (
    IN PCHAR Title,
    IN ULONG Iterations,
    IN PPERFINFO PerfInfo
    )

{

    NTSTATUS Status;
    SYSTEM_PERFORMANCE_INFORMATION SystemInfo;

    //
    // Announce start of test and the number of iterations.
    //

    printf("*** Start of test ***\n    %s\n", Title);
    PerfInfo->Title = Title;
    PerfInfo->Iterations = Iterations;
    NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StartTime);
    Status = NtQuerySystemInformation(SystemPerformanceInformation,
                                      (PVOID)&SystemInfo,
                                      sizeof(SYSTEM_PERFORMANCE_INFORMATION),
                                      NULL);

    if (NT_SUCCESS(Status) == FALSE) {
        printf("Failed to query performance information, status = %lx\n", Status);
        return;
    }

    PerfInfo->ContextSwitches = SystemInfo.ContextSwitches;
    PerfInfo->FirstLevelFills = SystemInfo.FirstLevelTbFills;
    PerfInfo->InterruptCount = SystemInfo.InterruptCount;
    PerfInfo->SecondLevelFills = SystemInfo.SecondLevelTbFills;
    PerfInfo->SystemCalls = SystemInfo.SystemCalls;
    return;
}
Ejemplo n.º 20
0
NTSTATUS
LogfWriteRecord(PLOGFILE LogFile,
                PEVENTLOGRECORD Record,
                SIZE_T BufSize)
{
    NTSTATUS Status;
    LARGE_INTEGER SystemTime;

    // ASSERT(sizeof(*Record) == sizeof(RecBuf));

    if (!Record || BufSize < sizeof(*Record))
        return STATUS_INVALID_PARAMETER;

    /* Lock the log file exclusive */
    RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);

    /*
     * Retrieve the record written time now, that will also be compared
     * with the existing events timestamps in case the log is wrapping.
     */
    NtQuerySystemTime(&SystemTime);
    RtlTimeToSecondsSince1970(&SystemTime, &Record->TimeWritten);

    Status = ElfWriteRecord(&LogFile->LogFile, Record, BufSize);
    if (Status == STATUS_LOG_FILE_FULL)
    {
        /* The event log file is full, queue a message box for the user and exit */
        // TODO!
        DPRINT1("Log file `%S' is full!\n", LogFile->LogName);
    }

    /* Unlock the log file */
    RtlReleaseResource(&LogFile->Lock);

    return Status;
}
Ejemplo n.º 21
0
/***********************************************************************
 *        NtSetSystemTime [NTDLL.@]
 *        ZwSetSystemTime [NTDLL.@]
 *
 * Set the system time.
 *
 * PARAMS
 *   NewTime [I] The time to set.
 *   OldTime [O] Optional destination for the previous system time.
 *
 * RETURNS
 *   Success: STATUS_SUCCESS.
 *   Failure: An NTSTATUS error code indicating the problem.
 */
NTSTATUS WINAPI NtSetSystemTime(const LARGE_INTEGER *NewTime, LARGE_INTEGER *OldTime)
{
    struct timeval tv;
    time_t tm_t;
    DWORD sec, oldsec;
    LARGE_INTEGER tm;

    /* Return the old time if necessary */
    if (!OldTime) OldTime = &tm;

    NtQuerySystemTime( OldTime );
    RtlTimeToSecondsSince1970( OldTime, &oldsec );

    RtlTimeToSecondsSince1970( NewTime, &sec );

    /* set the new time */
    tv.tv_sec = sec;
    tv.tv_usec = 0;

#ifdef HAVE_SETTIMEOFDAY
    if (!settimeofday(&tv, NULL)) /* 0 is OK, -1 is error */
        return STATUS_SUCCESS;
    tm_t = sec;
    ERR("Cannot set time to %s, time adjustment %ld: %s\n",
        ctime(&tm_t), (long)(sec-oldsec), strerror(errno));
    if (errno == EPERM)
        return STATUS_PRIVILEGE_NOT_HELD;
    else
        return STATUS_INVALID_PARAMETER;
#else
    tm_t = sec;
    FIXME("setting time to %s not implemented for missing settimeofday\n",
        ctime(&tm_t));
    return STATUS_NOT_IMPLEMENTED;
#endif
}
Ejemplo n.º 22
0
/* Function 28 */
NET_API_STATUS
__stdcall
NetrRemoteTOD(
    SRVSVC_HANDLE ServerName,
    LPTIME_OF_DAY_INFO *BufferPtr)
{
    SYSTEMTIME SystemTime;
    LARGE_INTEGER Time;
    TIME_ZONE_INFORMATION TimeZoneInfo;
    DWORD TimeZoneId;
    LPTIME_OF_DAY_INFO lpTod;

    TRACE("NetrRemoteTOD(%p %p)\n", ServerName, BufferPtr);

    *BufferPtr = midl_user_allocate(sizeof(TIME_OF_DAY_INFO));
    if (*BufferPtr == NULL)
        return ERROR_NOT_ENOUGH_MEMORY;

    lpTod = *BufferPtr;

    /* Set the seconds since 1970 */
    NtQuerySystemTime(&Time);
    RtlTimeToSecondsSince1970(&Time,
                              &lpTod->tod_elapsedt);

    /* Set the tick count */
    lpTod->tod_msecs = GetTickCount();

    /* Set the timezone */
    TimeZoneId = GetTimeZoneInformation(&TimeZoneInfo);

    switch (TimeZoneId)
    {
        case TIME_ZONE_ID_UNKNOWN:
            lpTod->tod_timezone = TimeZoneInfo.Bias;
            break;

        case TIME_ZONE_ID_STANDARD:
            lpTod->tod_timezone = TimeZoneInfo.Bias + TimeZoneInfo.StandardBias;
            break;

        case TIME_ZONE_ID_DAYLIGHT:
            lpTod->tod_timezone = TimeZoneInfo.Bias + TimeZoneInfo.DaylightBias;
            break;

        default:
            lpTod->tod_timezone = 0;
    }

    /* Set the ??? */
    lpTod->tod_tinterval = 310;

    /* Set the date and time */
    GetSystemTime(&SystemTime);
    lpTod->tod_hours = SystemTime.wHour;
    lpTod->tod_mins = SystemTime.wMinute;
    lpTod->tod_secs = SystemTime.wSecond;
    lpTod->tod_hunds = SystemTime.wMilliseconds / 10;
    lpTod->tod_day = SystemTime.wDay;
    lpTod->tod_month = SystemTime.wMonth;
    lpTod->tod_year = SystemTime.wYear;
    lpTod->tod_weekday = SystemTime.wDayOfWeek;

    return NERR_Success;
}
Ejemplo n.º 23
0
Archivo: tod.c Proyecto: mingpen/OpenNT
NTSTATUS
timesvc_RemoteTimeOfDay(
    OUT LPTIME_OF_DAY_INFO  *lpTimeOfDayInfo
    )

/*++

Routine Description:

    This routine calls the Win32 and NT base timer APIs to get the
    relevant time/date information. It also calls the Rtl routine to
    convert the time elapsed since 1-1-1970.

    The routine allocates a buffer to contain the time of day information
    and returns a pointer to that buffer to the caller.

Arguments:

    lpTimeOfDayInfo        - Location of where to place pointer to buffer.

Return Value:

    NTSTATUS - STATUS_SUCCESS or reason for failure.

--*/

{
    SYSTEMTIME SystemTime;
    LARGE_INTEGER Time;
    DWORD TickCount;
    LPTIME_OF_DAY_INFO        lpTimeOfDay;
    LONG LocalTimeZoneOffsetSecs;  // offset (+ for West of GMT, etc).

    if (lpTimeOfDayInfo == NULL) {
        return (STATUS_INVALID_PARAMETER);
    }

    //
    // Call the appropriate routines to collect the time information
    //

    GetSystemTime(&SystemTime);

    //
    // Get number of seconds from UTC.  Positive values for west of Greenwich,
    // negative values for east of Greenwich.
    //
    LocalTimeZoneOffsetSecs = NetpLocalTimeZoneOffset();

    //
    // Allocate a TimeOfDay_INFO structure that is to be returned to the
    // caller and fill it with the relevant data.
    //

    *lpTimeOfDayInfo = (TIME_OF_DAY_INFO *) MIDL_user_allocate(
                            sizeof (struct _TIME_OF_DAY_INFO)
                            );

    if (*lpTimeOfDayInfo == NULL) {
        SS_PRINT((
                "SRVSVC: timesvc_RemoteTimeOfDay"
                "got NULL from MIDL_user_allocate!\n" ));
        return(STATUS_NO_MEMORY);
    }

    lpTimeOfDay = (LPTIME_OF_DAY_INFO)(*lpTimeOfDayInfo);

    lpTimeOfDay->tod_hours         = SystemTime.wHour;
    lpTimeOfDay->tod_mins         = SystemTime.wMinute;
    lpTimeOfDay->tod_secs         = SystemTime.wSecond;
    lpTimeOfDay->tod_hunds         = SystemTime.wMilliseconds/10;
    lpTimeOfDay->tod_tinterval = TOD_DEFAULT_INTERVAL;
    lpTimeOfDay->tod_day         = SystemTime.wDay;
    lpTimeOfDay->tod_month         = SystemTime.wMonth;
    lpTimeOfDay->tod_year         = SystemTime.wYear;
    lpTimeOfDay->tod_weekday         = SystemTime.wDayOfWeek;

    // tod_timezone is + for west of GMT, - for east of it.
    // tod_timezone is in minutes.
    lpTimeOfDay->tod_timezone    = LocalTimeZoneOffsetSecs / 60;

    // Get the 64-bit system time.
    // Convert the system time to the number of miliseconds
    // since 1-1-1970.
    //

    NtQuerySystemTime(&Time);
    RtlTimeToSecondsSince1970(&Time,
                              &(lpTimeOfDay->tod_elapsedt)
                             );

    // Get the free running counter value
    //
    TickCount = GetTickCount();
    lpTimeOfDay->tod_msecs = TickCount;

    return(STATUS_SUCCESS);

} // timesvc_RemoteTimeOfDay
Ejemplo n.º 24
0
static void test_tp_wait(void)
{
    TP_CALLBACK_ENVIRON environment;
    TP_WAIT *wait1, *wait2;
    struct wait_info info;
    HANDLE semaphores[2];
    LARGE_INTEGER when;
    NTSTATUS status;
    TP_POOL *pool;
    DWORD result;

    semaphores[0] = CreateSemaphoreW(NULL, 0, 2, NULL);
    ok(semaphores[0] != NULL, "failed to create semaphore\n");
    semaphores[1] = CreateSemaphoreW(NULL, 0, 1, NULL);
    ok(semaphores[1] != NULL, "failed to create semaphore\n");
    info.semaphore = semaphores[0];

    /* allocate new threadpool */
    pool = NULL;
    status = pTpAllocPool(&pool, NULL);
    ok(!status, "TpAllocPool failed with status %x\n", status);
    ok(pool != NULL, "expected pool != NULL\n");

    /* allocate new wait items */
    memset(&environment, 0, sizeof(environment));
    environment.Version = 1;
    environment.Pool = pool;

    wait1 = NULL;
    status = pTpAllocWait(&wait1, wait_cb, &info, &environment);
    ok(!status, "TpAllocWait failed with status %x\n", status);
    ok(wait1 != NULL, "expected wait1 != NULL\n");

    wait2 = NULL;
    status = pTpAllocWait(&wait2, wait_cb, &info, &environment);
    ok(!status, "TpAllocWait failed with status %x\n", status);
    ok(wait2 != NULL, "expected wait2 != NULL\n");

    /* infinite timeout, signal the semaphore immediately */
    info.userdata = 0;
    pTpSetWait(wait1, semaphores[1], NULL);
    ReleaseSemaphore(semaphores[1], 1, NULL);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[1], 0);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);

    /* relative timeout, no event */
    info.userdata = 0;
    when.QuadPart = (ULONGLONG)200 * -10000;
    pTpSetWait(wait1, semaphores[1], &when);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[0], 200);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[1], 0);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);

    /* repeat test with call to TpWaitForWait(..., TRUE) */
    info.userdata = 0;
    when.QuadPart = (ULONGLONG)200 * -10000;
    pTpSetWait(wait1, semaphores[1], &when);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);
    pTpWaitForWait(wait1, TRUE);
    ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[0], 200);
    ok(result == WAIT_OBJECT_0 || broken(result == WAIT_TIMEOUT) /* Win 8 */,
       "WaitForSingleObject returned %u\n", result);
    if (result == WAIT_OBJECT_0)
        ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata);
    else
        ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[1], 0);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);

    /* relative timeout, with event */
    info.userdata = 0;
    when.QuadPart = (ULONGLONG)200 * -10000;
    pTpSetWait(wait1, semaphores[1], &when);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata);
    ReleaseSemaphore(semaphores[1], 1, NULL);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[1], 0);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);

    /* repeat test with call to TpWaitForWait(..., TRUE) */
    info.userdata = 0;
    when.QuadPart = (ULONGLONG)200 * -10000;
    pTpSetWait(wait1, semaphores[1], &when);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);
    pTpWaitForWait(wait1, TRUE);
    ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata);
    ReleaseSemaphore(semaphores[1], 1, NULL);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_OBJECT_0 || broken(result == WAIT_TIMEOUT) /* Win 8 */,
       "WaitForSingleObject returned %u\n", result);
    if (result == WAIT_OBJECT_0)
    {
        ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata);
        result = WaitForSingleObject(semaphores[1], 0);
        ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);
    }
    else
    {
        ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata);
        result = WaitForSingleObject(semaphores[1], 0);
        ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
    }

    /* absolute timeout, no event */
    info.userdata = 0;
    NtQuerySystemTime( &when );
    when.QuadPart += (ULONGLONG)200 * 10000;
    pTpSetWait(wait1, semaphores[1], &when);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[0], 200);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[1], 0);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);

    /* absolute timeout, with event */
    info.userdata = 0;
    NtQuerySystemTime( &when );
    when.QuadPart += (ULONGLONG)200 * 10000;
    pTpSetWait(wait1, semaphores[1], &when);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata);
    ReleaseSemaphore(semaphores[1], 1, NULL);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[1], 0);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);

    /* test timeout of zero */
    info.userdata = 0;
    when.QuadPart = 0;
    pTpSetWait(wait1, semaphores[1], &when);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[1], 0);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);

    /* cancel a pending wait */
    info.userdata = 0;
    when.QuadPart = (ULONGLONG)250 * -10000;
    pTpSetWait(wait1, semaphores[1], &when);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);
    pTpSetWait(wait1, NULL, (void *)0xdeadbeef);
    Sleep(50);
    ReleaseSemaphore(semaphores[1], 1, NULL);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[1], 0);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);

    /* test with INVALID_HANDLE_VALUE */
    info.userdata = 0;
    when.QuadPart = 0;
    pTpSetWait(wait1, INVALID_HANDLE_VALUE, &when);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata);

    /* cancel a pending wait with INVALID_HANDLE_VALUE */
    info.userdata = 0;
    when.QuadPart = (ULONGLONG)250 * -10000;
    pTpSetWait(wait1, semaphores[1], &when);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);
    when.QuadPart = 0;
    pTpSetWait(wait1, INVALID_HANDLE_VALUE, &when);
    Sleep(50);
    ReleaseSemaphore(semaphores[1], 1, NULL);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[1], 0);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);

    CloseHandle(semaphores[1]);
    semaphores[1] = CreateSemaphoreW(NULL, 0, 2, NULL);
    ok(semaphores[1] != NULL, "failed to create semaphore\n");

    /* add two wait objects with the same semaphore */
    info.userdata = 0;
    pTpSetWait(wait1, semaphores[1], NULL);
    pTpSetWait(wait2, semaphores[1], NULL);
    Sleep(50);
    ReleaseSemaphore(semaphores[1], 1, NULL);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[1], 0);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);

    /* repeat test above with release count 2 */
    info.userdata = 0;
    pTpSetWait(wait1, semaphores[1], NULL);
    pTpSetWait(wait2, semaphores[1], NULL);
    Sleep(50);
    result = ReleaseSemaphore(semaphores[1], 2, NULL);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
    result = WaitForSingleObject(semaphores[0], 100);
    ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
    ok(info.userdata == 2, "expected info.userdata = 2, got %u\n", info.userdata);
    result = WaitForSingleObject(semaphores[1], 0);
    ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result);

    /* cleanup */
    pTpReleaseWait(wait1);
    pTpReleaseWait(wait2);
    pTpReleasePool(pool);
    CloseHandle(semaphores[0]);
    CloseHandle(semaphores[1]);
}
Ejemplo n.º 25
0
/***********************************************************************
 *           thread_init
 *
 * Setup the initial thread.
 *
 * NOTES: The first allocated TEB on NT is at 0x7ffde000.
 */
HANDLE thread_init(void)
{
    TEB *teb;
    void *addr;
    SIZE_T size, info_size;
    HANDLE exe_file = 0;
    LARGE_INTEGER now;
    NTSTATUS status;
    struct ntdll_thread_data *thread_data;
    static struct debug_info debug_info;  /* debug info for initial thread */

    virtual_init();

    /* reserve space for shared user data */

    addr = (void *)0x7ffe0000;
    size = 0x10000;
    status = NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size,
                                      MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
    if (status)
    {
        MESSAGE( "wine: failed to map the shared user data: %08x\n", status );
        exit(1);
    }
    user_shared_data = addr;

    /* allocate and initialize the PEB */

    addr = NULL;
    size = sizeof(*peb);
    NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 1, &size,
                             MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE );
    peb = addr;

    peb->ProcessParameters  = &params;
    peb->TlsBitmap          = &tls_bitmap;
    peb->TlsExpansionBitmap = &tls_expansion_bitmap;
    peb->FlsBitmap          = &fls_bitmap;
    peb->LdrData            = &ldr;
    params.CurrentDirectory.DosPath.Buffer = current_dir;
    params.CurrentDirectory.DosPath.MaximumLength = sizeof(current_dir);
    params.wShowWindow = 1; /* SW_SHOWNORMAL */
    ldr.Length = sizeof(ldr);
    RtlInitializeBitMap( &tls_bitmap, peb->TlsBitmapBits, sizeof(peb->TlsBitmapBits) * 8 );
    RtlInitializeBitMap( &tls_expansion_bitmap, peb->TlsExpansionBitmapBits,
                         sizeof(peb->TlsExpansionBitmapBits) * 8 );
    RtlInitializeBitMap( &fls_bitmap, peb->FlsBitmapBits, sizeof(peb->FlsBitmapBits) * 8 );
    InitializeListHead( &peb->FlsListHead );
    InitializeListHead( &ldr.InLoadOrderModuleList );
    InitializeListHead( &ldr.InMemoryOrderModuleList );
    InitializeListHead( &ldr.InInitializationOrderModuleList );
#ifdef __APPLE__
    peb->Reserved[0] = get_dyld_image_info_addr();
#endif

    /* allocate and initialize the initial TEB */

    signal_alloc_thread( &teb );
    teb->Peb = peb;
    teb->Tib.StackBase = (void *)~0UL;
    teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
    teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);

    thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
    thread_data->request_fd = -1;
    thread_data->reply_fd   = -1;
    thread_data->wait_fd[0] = -1;
    thread_data->wait_fd[1] = -1;
    thread_data->debug_info = &debug_info;
    InsertHeadList( &tls_links, &teb->TlsLinks );

    signal_init_thread( teb );
    virtual_init_threading();

    debug_info.str_pos = debug_info.strings;
    debug_info.out_pos = debug_info.output;
    debug_init();

    /* setup the server connection */
    server_init_process();
    info_size = server_init_thread( peb );

    /* create the process heap */
    if (!(peb->ProcessHeap = RtlCreateHeap( HEAP_GROWABLE, NULL, 0, 0, NULL, NULL )))
    {
        MESSAGE( "wine: failed to create the process heap\n" );
        exit(1);
    }

    /* allocate user parameters */
    if (info_size)
    {
        init_user_process_params( info_size, &exe_file );
    }
    else
    {
        if (isatty(0) || isatty(1) || isatty(2))
            params.ConsoleHandle = (HANDLE)2; /* see kernel32/kernel_private.h */
        if (!isatty(0))
            wine_server_fd_to_handle( 0, GENERIC_READ|SYNCHRONIZE,  OBJ_INHERIT, &params.hStdInput );
        if (!isatty(1))
            wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, &params.hStdOutput );
        if (!isatty(2))
            wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, &params.hStdError );
    }

    /* initialize time values in user_shared_data */
    NtQuerySystemTime( &now );
    user_shared_data->SystemTime.LowPart = now.u.LowPart;
    user_shared_data->SystemTime.High1Time = user_shared_data->SystemTime.High2Time = now.u.HighPart;
    user_shared_data->u.TickCountQuad = (now.QuadPart - server_start_time) / 10000;
    user_shared_data->u.TickCount.High2Time = user_shared_data->u.TickCount.High1Time;
    user_shared_data->TickCountLowDeprecated = user_shared_data->u.TickCount.LowPart;
    user_shared_data->TickCountMultiplier = 1 << 24;

    fill_cpu_info();

    NtCreateKeyedEvent( &keyed_event, GENERIC_READ | GENERIC_WRITE, NULL, 0 );

    return exe_file;
}
Ejemplo n.º 26
0
void
_CRTAPI1 main(int, char *)
{
    NTSTATUS status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING  KeyName;
    UNICODE_STRING  KeyName2;
    UNICODE_STRING  ClassName;
    UNICODE_STRING  ClassName2;
    UNICODE_STRING  ValueName;
    UNICODE_STRING  ValueName2;
    HANDLE          BaseHandle;
    HANDLE          Testhand1;
    ULONG           Disposition;
    LARGE_INTEGER   CompTime;
    ULONG           buffer[100];
    ULONG           bufsize = sizeof(ULONG) * 100;
    PKEY_NODE_INFORMATION NodeInformation;
    PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
    PKEY_VALUE_BASIC_INFORMATION KeyValueBasic;
    ULONG           ResultLength;
    PUCHAR          datastring = "Some simple ascii data for use as a value";
    PUCHAR          datastring2 = "Some more not so simple data $#";
    ULONG           expected;
    PVOID           tp;


    printf("rtmisc1: starting\n");

    NodeInformation = (PKEY_NODE_INFORMATION)&(buffer[0]);
    KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)&(buffer[0]);
    KeyValueBasic = (PKEY_VALUE_BASIC_INFORMATION)&(buffer[0]);

    //
    // t0: Perform all operations against a base node, open it here.
    //

    RtlInitUnicodeString(
        &KeyName,
        L"\\REGISTRY\\MACHINE\\TEST"
        );

    InitializeObjectAttributes(
        &ObjectAttributes,
        &KeyName,
        0,
        (HANDLE)NULL,
        NULL
        );
    ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

    status = NtOpenKey(
                &BaseHandle,
                MAXIMUM_ALLOWED,
                &ObjectAttributes
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t0: %08lx\n", status);
        goto punt;
    }


    //
    // t1: Create a key with class and title index
    //

    RtlInitUnicodeString(
        &ClassName,
        L"t1 Class Name"
        );

    RtlInitUnicodeString(
        &KeyName,
        L"first_test_node"
        );

    InitializeObjectAttributes(
        &ObjectAttributes,
        &KeyName,
        0,
        BaseHandle,
        NULL
        );
    ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

    NtQuerySystemTime(&CompTime);

//  printf("ClassName@%08lx  KeyName@%08lx\n",
//          ClassName.Buffer, KeyName.Buffer);

    status = NtCreateKey(
                &Testhand1,
                MAXIMUM_ALLOWED,
                &ObjectAttributes,
                TITLE_INDEX_1,
                &ClassName,
                0,
                &Disposition
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t1: %08lx\n", status);
        goto punt;
    }

    if (Disposition != REG_CREATED_NEW_KEY) {
        printf("rtmisc1: t1a: got old key, expected to create new one\n");
        failure++;
    }

    //
    // t2: See if we can get data back, and if it makes sense
    //

    RtlZeroMemory(NodeInformation, bufsize);
    status = NtQueryKey(
                Testhand1,
                KeyNodeInformation,
                NodeInformation,
                bufsize,
                &ResultLength
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t2a: %08lx\n", status);
        goto punt;
    }
    if (ResultLength != 80) {
        printf("rtmisc1: t2i: expect 80, ResultLength = %d\n", ResultLength);
        failure++;
    }


    NameClassAndTitle(
        NodeInformation,
        ClassName,
        TITLE_INDEX_1,
        KeyName,
        CompTime,
        FALSE,          // time must be >= CompTime
        "rtmisc1: t2b: "
        );
    CompTime = NodeInformation->LastWriteTime;

    status = NtClose(Testhand1);
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t2c: %08lx\n");
        goto punt;
    }


    //
    // t3: Reopen the key with create, see if data still there.
    //

    status = NtCreateKey(
                &Testhand1,
                MAXIMUM_ALLOWED,
                &ObjectAttributes,
                TITLE_INDEX_1,
                &ClassName,
                0,
                &Disposition
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t3: %08lx\n", status);
        goto punt;
    }

    if (Disposition != REG_OPENED_EXISTING_KEY) {
        printf("rtmisc1: t3a failure\n");
        failure++;
    }

    RtlZeroMemory(NodeInformation, bufsize);
    status = NtQueryKey(
                Testhand1,
                KeyNodeInformation,
                NodeInformation,
                bufsize,
                &ResultLength
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t3b: %08lx\n", status);
        goto punt;
    }

    NameClassAndTitle(
        NodeInformation,
        ClassName,
        TITLE_INDEX_1,
        KeyName,
        CompTime,
        FALSE,          // time must be >= CompTime
        "rtmisc1: t3c: "
        );

    status = NtClose(Testhand1);
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t3d: %08lx\n");
        goto punt;
    }


    //
    // t4: Reopen the key with open, see if data still there.
    //

    status = NtOpenKey(
                &Testhand1,
                MAXIMUM_ALLOWED,
                &ObjectAttributes
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t4: %08lx\n", status);
        goto punt;
    }

    RtlZeroMemory(NodeInformation, bufsize);
    status = NtQueryKey(
                Testhand1,
                KeyNodeInformation,
                NodeInformation,
                bufsize,
                &ResultLength
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t4a: %08lx\n", status);
        goto punt;
    }

    NameClassAndTitle(
        NodeInformation,
        ClassName,
        TITLE_INDEX_1,
        KeyName,
        CompTime,
        FALSE,          // time must be >= CompTime
        "rtmisc1: t4b: "
        );

//  status = NtClose(Testhand1);
//  if (!NT_SUCCESS(status)) {
//      printf("rtmisc1: t4c: %08lx\n");
//      exit(1);
//  }


    //
    // t5: Create a value
    //

    RtlInitUnicodeString(
        &ValueName,
        L"the very first value stored in the registry"
        );


    status = NtSetValueKey(
                Testhand1,
                &ValueName,
                TITLE_INDEX_2,
                TYPE_1,
                datastring,
                strlen(datastring)+1
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t5: %08lx\n", status);
        failure++;
    }


    //
    // t6: Read the value back
    //

    RtlZeroMemory(KeyValueInformation, bufsize);
    status = NtQueryValueKey(
                Testhand1,
                &ValueName,
                KeyValueFullInformation,
                KeyValueInformation,
                bufsize,
                &ResultLength
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t6: %08lx\n", status);
        goto punt;
    }
    expected = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name) +
                    ValueName.Length + strlen(datastring) + 1;
    if (ResultLength != expected) {
        printf("rtmisc1: t6a: expected = %08lx actual = %08lx",
                expected, ResultLength);
        failure++;
    }

    if ( (KeyValueInformation->TitleIndex != TITLE_INDEX_2)         ||
         (KeyValueInformation->Type != TYPE_1)                      ||
         (KeyValueInformation->NameLength != ValueName.Length)      ||
         (KeyValueInformation->DataLength != strlen(datastring)+1))
    {
        printf("rtmisc1: t6b: wrong description data\n");
        failure++;
    }


    tp = (PWSTR)&(KeyValueInformation->Name[0]);
    if (wcsncmp(ValueName.Buffer, tp, (ValueName.Length/sizeof(WCHAR))) != 0) {
        printf("rtmisc1: t6c: wrong name\n");
        expectstring(
            ValueName.Buffer,
            (ValueName.Length/sizeof(WCHAR)),
            (PWSTR)&(KeyValueInformation->Name[0]),
            (KeyValueInformation->NameLength/sizeof(WCHAR))
            );
        failure++;
    }


    tp = (PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset;
    if (strcmp(tp, datastring) != 0) {
        printf("rtmisc1: t6d: wrong data\n");
        printf("expected '%s', got '%s'\n", datastring, tp);
        failure++;
    }

    //
    // t7: Create a second value
    //

    RtlInitUnicodeString(
        &ValueName2,
        L"the second value stored in the registry"
        );


    status = NtSetValueKey(
                Testhand1,
                &ValueName2,
                TITLE_INDEX_3,
                TYPE_2,
                datastring2,
                strlen(datastring2)+1
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t7: %08lx\n", status);
        failure++;
    }

    //
    // t8: Read the second value back (short form)
    //

    RtlZeroMemory(KeyValueBasic, bufsize);
    status = NtQueryValueKey(
                Testhand1,
                &ValueName2,
                KeyValueBasicInformation,
                KeyValueBasic,
                bufsize,
                &ResultLength
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t8: %08lx\n", status);
        goto punt;
    }

    expected = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
                    ValueName2.Length;
    if (ResultLength != expected) {
        printf("rtmisc1: t8a: expected = %08lx actual = %08lx",
                expected, ResultLength);
        failure++;
    }

    if ( (KeyValueBasic->TitleIndex != TITLE_INDEX_3)         ||
         (KeyValueBasic->Type != TYPE_2)                      ||
         (KeyValueBasic->NameLength != ValueName2.Length))
    {
        printf("rtmisc1: t8b: wrong description data\n");
        failure++;
    }


    tp = (PWSTR)&(KeyValueBasic->Name[0]);
    if (wcsncmp(ValueName2.Buffer, tp, (ValueName2.Length/sizeof(WCHAR))) != 0) {
        printf("rtmisc1: t8c: wrong name\n");
        expectstring(
            ValueName2.Buffer,
            (ValueName2.Length/sizeof(WCHAR)),
            (PWSTR)&(KeyValueBasic->Name[0]),
            (KeyValueBasic->NameLength/sizeof(WCHAR))
            );
        failure++;
    }


    //
    // t9: Enumerate the values (short form)
    //

    RtlZeroMemory(KeyValueBasic, bufsize);
    status = NtEnumerateValueKey(
                Testhand1,
                0,              // Index
                KeyValueBasicInformation,
                KeyValueBasic,
                bufsize,
                &ResultLength
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t9: %08lx\n", status);
        goto punt;
    }

    expected = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
                    ValueName.Length;
    if (ResultLength != expected) {
        printf("rtmisc1: t9a: expected = %08lx actual = %08lx",
                expected, ResultLength);
        failure++;
    }

    if (KeyValueBasic->NameLength != ValueName.Length)
    {
        printf("rtmisc1: t9b: wrong description data\n");
        failure++;
    }


    tp = (PWSTR)&(KeyValueBasic->Name[0]);
    if (wcsncmp(ValueName.Buffer, tp, (ValueName.Length/sizeof(WCHAR))) != 0) {
        printf("rtmisc1: t9c: wrong name\n");
        expectstring(
            ValueName.Buffer,
            (ValueName.Length/sizeof(WCHAR)),
            (PWSTR)&(KeyValueBasic->Name[0]),
            (KeyValueBasic->NameLength/sizeof(WCHAR))
            );
        failure++;
    }

    RtlZeroMemory(KeyValueBasic, bufsize);
    status = NtEnumerateValueKey(
                Testhand1,
                1,              // Index
                KeyValueBasicInformation,
                KeyValueBasic,
                bufsize,
                &ResultLength
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t9d: %08lx\n", status);
        goto punt;
    }

    expected = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
                    ValueName2.Length;
    if (ResultLength != expected) {
        printf("rtmisc1: t9e: expected = %08lx actual = %08lx",
                expected, ResultLength);
        failure++;
    }

    if (KeyValueBasic->NameLength != ValueName2.Length)
    {
        printf("rtmisc1: t9f: wrong description data\n");
        failure++;
    }


    tp = (PWSTR)&(KeyValueBasic->Name[0]);
    if (wcsncmp(ValueName2.Buffer, tp, (ValueName2.Length/sizeof(WCHAR))) != 0) {
        printf("rtmisc1: t9g: wrong name\n");
        expectstring(
            ValueName2.Buffer,
            (ValueName2.Length/sizeof(WCHAR)),
            (PWSTR)&(KeyValueBasic->Name[0]),
            (KeyValueBasic->NameLength/sizeof(WCHAR))
            );
        failure++;
    }

    status = NtEnumerateValueKey(
                Testhand1,
                2,              // Index
                KeyValueBasicInformation,
                KeyValueBasic,
                bufsize,
                &ResultLength
                );
    if (status != STATUS_NO_MORE_ENTRIES) {
        printf("rtmisc1: t9h: %08lx\n", status);
        goto punt;
    }

    //
    // t10: create a second subkey and ennumerate the subkeys
    //

    status = NtClose(Testhand1);
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t10a: %08lx\n", status);
        failure++;
    }

    RtlInitUnicodeString(
        &ClassName2,
        L"t2 Class Name"
        );

    RtlInitUnicodeString(
        &KeyName2,
        L"second_test_node"
        );

    InitializeObjectAttributes(
        &ObjectAttributes,
        &KeyName2,
        0,
        BaseHandle,
        NULL
        );
    ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

    status = NtCreateKey(
                &Testhand1,
                MAXIMUM_ALLOWED,
                &ObjectAttributes,
                TITLE_INDEX_2,
                &ClassName2,
                0,
                &Disposition
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t10b: %08lx\n", status);
        goto punt;
    }

    if (Disposition != REG_CREATED_NEW_KEY) {
        printf("rtmisc1: t10c: got old key, expected to create new one\n");
        failure++;
    }

    //
    // See if we can get data back, and if it makes sense
    //

    RtlZeroMemory(NodeInformation, bufsize);
    status = NtQueryKey(
                Testhand1,
                KeyNodeInformation,
                NodeInformation,
                bufsize,
                &ResultLength
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t10d: %08lx\n", status);
        goto punt;
    }
    CompTime = NodeInformation->LastWriteTime;


    NameClassAndTitle(
        NodeInformation,
        ClassName2,
        TITLE_INDEX_2,
        KeyName2,
        CompTime,
        TRUE,
        "rtmisc1: t10e: "
        );

    status = NtClose(Testhand1);
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t10f: %08lx\n");
        goto punt;
    }


    RtlZeroMemory(NodeInformation, bufsize);
    status = NtEnumerateKey(
                BaseHandle,
                0,
                KeyNodeInformation,
                NodeInformation,
                bufsize,
                &ResultLength
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t10g: %08lx\n", status);
        failure++;
    }
    CompTime = NodeInformation->LastWriteTime;

    NameClassAndTitle(
        NodeInformation,
        ClassName,
        TITLE_INDEX_1,
        KeyName,
        CompTime,
        TRUE,
        "rtmisc1: t10h: "
        );


    RtlZeroMemory(NodeInformation, bufsize);
    status = NtEnumerateKey(
                BaseHandle,
                1,
                KeyNodeInformation,
                NodeInformation,
                bufsize,
                &ResultLength
                );
    if (!NT_SUCCESS(status)) {
        printf("rtmisc1: t10i: %08lx\n", status);
        failure++;
    }
    CompTime = NodeInformation->LastWriteTime;

    NameClassAndTitle(
        NodeInformation,
        ClassName2,
        TITLE_INDEX_2,
        KeyName2,
        CompTime,
        TRUE,
        "rtmisc1: t10j: "
        );


    status = NtEnumerateKey(
                BaseHandle,
                2,
                KeyNodeInformation,
                NodeInformation,
                bufsize,
                &ResultLength
                );
    if (status != STATUS_NO_MORE_ENTRIES) {
        printf("rtmisc1: t10k: %08lx\n", status);
        failure++;
    }

    //
    // Summary report
    //

    if (!failure) {
        printf("rtmisc1: success");
        exit(0);
    } else {
        printf("rtmisc1: failed, %d failures\n", failure);
        exit(1);
    }

punt:
    failure++;
    printf("rtmisc1: failed, %d failures\n", failure);
    exit(1);
}
Ejemplo n.º 27
0
NTSTATUS
LsarCreateSecret(
    IN LSAPR_HANDLE PolicyHandle,
    IN PLSAPR_UNICODE_STRING SecretName,
    IN ACCESS_MASK DesiredAccess,
    OUT PLSAPR_HANDLE SecretHandle
    )

/*++

Routine Description:

    This function is the LSA server RPC worker routine for the
    LsaCreateSecret API.

    The LsaCreateSecret API creates a named Secret object in the
    Lsa Database.  Each Secret Object can have two values assigned,
    called the Current Value and the Old Value.  The meaning of these
    values is known to the Secret object creator.  The caller must have
    LSA_CREATE_SECRET access to the LsaDatabase object.

Arguments:

    PolicyHandle -  Handle from an LsaOpenPolicy call.

    SecretName - Pointer to Unicode String specifying the name of the
        secret.

    DesiredAccess - Specifies the accesses to be granted to the newly
        created and opened secret.

    SecretHandle - Receives a handle to the newly created and opened
        Secret object.  This handle is used on subsequent accesses to
        the object until closed.

Return Values:

    NTSTATUS - Standard Nt Result Code

        STATUS_ACCESS_DENIED - Caller does not have the appropriate access
            to complete the operation.

        STATUS_OBJECT_NAME_COLLISION - A Secret object having the given name
            already exists.

        STATUS_TOO_MANY_SECRETS - The maximum number of Secret objects in the
            system has been reached.

        STATUS_NAME_TOO_LONG - The name of the secret is too long to be stored
            in the LSA database.
--*/

{
    NTSTATUS Status;
    LSAP_DB_OBJECT_INFORMATION ObjectInformation;
    BOOLEAN ContainerReferenced = FALSE;
    LSAP_DB_ATTRIBUTE Attributes[2];
    ULONG TypeSpecificAttributeCount;
    LARGE_INTEGER CreationTime;
    ULONG Index;
    ULONG CreateOptions = (ULONG) 0;
    ULONG ReferenceOptions = (ULONG) LSAP_DB_ACQUIRE_LOCK;
    ULONG DereferenceOptions = (ULONG) LSAP_DB_RELEASE_LOCK;
    BOOLEAN GlobalSecret = FALSE;


    //
    // Check to see if the lenght of the name is within the limits of the
    // LSA database.
    //

    if ( SecretName->Length > LSAP_DB_LOGICAL_NAME_MAX_LENGTH ) {
        return(STATUS_NAME_TOO_LONG);
    }

    //
    // Check for Local Secret creation request.  If the Secret name does
    // not begin with the Global Secret Prefix, the Secret is local.  In
    // this case, creation of the secret is allowed on BDC's as well as
    // PDC's and Workstations.  Creation of Global Secrets is not
    // allowed on BDC's except for trusted callers such as a Replicator.
    //

    Status = LsapDbGetScopeSecret( SecretName, &GlobalSecret );

    if (!NT_SUCCESS(Status)) {

        goto CreateSecretError;
    }

    if (!GlobalSecret) {

        CreateOptions |= (LSAP_DB_OMIT_REPLICATOR_NOTIFICATION |
                          LSAP_DB_OMIT_BACKUP_CONTROLLER_CHECK);
        ReferenceOptions |= (LSAP_DB_OMIT_REPLICATOR_NOTIFICATION |
                            LSAP_DB_OMIT_BACKUP_CONTROLLER_CHECK);
    }

    //
    // Acquire the Lsa Database lock.  Verify that the connection handle
    // (container object handle) is valid, is of the expected type and has
    // all of the desired accesses granted.  Reference the container
    // object handle.
    //

    Status = LsapDbReferenceObject(
                 PolicyHandle,
                 POLICY_CREATE_SECRET,
                 PolicyObject,
                 ReferenceOptions
                 );

    if (!NT_SUCCESS(Status)) {

        goto CreateSecretError;
    }

    ContainerReferenced = TRUE;

    //
    // Fill in the ObjectInformation structure.  Initialize the
    // embedded Object Attributes with the PolicyHandle as the
    // Root Directory (Container Object) handle and the Logical Name
    // of the account. Store the types of the object and its container.
    //

    InitializeObjectAttributes(
        &ObjectInformation.ObjectAttributes,
        (PUNICODE_STRING)SecretName,
        OBJ_CASE_INSENSITIVE,
        PolicyHandle,
        NULL
        );

    ObjectInformation.ObjectTypeId = SecretObject;
    ObjectInformation.ContainerTypeId = PolicyObject;
    ObjectInformation.Sid = NULL;

    //
    // Set up the Creation Time as a Type Specific Attribute.
    //

    Status = NtQuerySystemTime(&CreationTime);

    if (!NT_SUCCESS(Status)) {

        goto CreateSecretError;
    }

    Index = 0;

    Attributes[Index].AttributeName = &LsapDbNames[CupdTime];
    Attributes[Index].AttributeValue = &CreationTime;
    Attributes[Index].AttributeValueLength = sizeof (LARGE_INTEGER);
    Index++;

    Attributes[Index].AttributeName = &LsapDbNames[OupdTime];
    Attributes[Index].AttributeValue = &CreationTime;
    Attributes[Index].AttributeValueLength = sizeof (LARGE_INTEGER);
    Index++;

    TypeSpecificAttributeCount = Index;

    //
    // Create the Secret Object.  We fail if the object already exists.
    // Note that the object create routine performs a Database transaction.
    //

    Status = LsapDbCreateObject(
                 &ObjectInformation,
                 DesiredAccess,
                 LSAP_DB_OBJECT_CREATE,
                 CreateOptions,
                 Attributes,
                 TypeSpecificAttributeCount,
                 SecretHandle
                 );

    if (!NT_SUCCESS(Status)) {

        goto CreateSecretError;
    }

CreateSecretFinish:

    //
    // If necessary, release the LSA Database lock.
    //

    if (ContainerReferenced) {

        LsapDbReleaseLock();
    }

#ifdef TRACK_HANDLE_CLOSE
    if (*SecretHandle == LsapDbHandle)
    {
        DbgPrint("BUGBUG: Closing global policy handle\n");
        DbgBreakPoint();
    }
#endif
    return( Status );

CreateSecretError:

    //
    // If necessary, dereference the Container Object.
    //

    if (ContainerReferenced) {

        Status = LsapDbDereferenceObject(
                     &PolicyHandle,
                     PolicyObject,
                     DereferenceOptions,
                     (SECURITY_DB_DELTA_TYPE) 0,
                     Status
                     );

        ContainerReferenced = FALSE;
    }

    goto CreateSecretFinish;

}
Ejemplo n.º 28
0
/*
 * @unimplemented
 */
NTSTATUS
NTAPI
LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
               IN SECURITY_LOGON_TYPE LogonType,
               IN PVOID AuthenticationInformation,
               IN PVOID ClientAuthenticationBase,
               IN ULONG AuthenticationInformationLength,
               OUT PVOID *ProfileBuffer,
               OUT PULONG ProfileBufferLength,
               OUT PLUID LogonId,
               OUT PNTSTATUS SubStatus,
               OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
               OUT PVOID *TokenInformation,
               OUT PLSA_UNICODE_STRING *AccountName,
               OUT PLSA_UNICODE_STRING *AuthenticatingAuthority)
{
    PMSV1_0_INTERACTIVE_LOGON LogonInfo;

    SAMPR_HANDLE ServerHandle = NULL;
    SAMPR_HANDLE DomainHandle = NULL;
    SAMPR_HANDLE UserHandle = NULL;
    PRPC_SID AccountDomainSid = NULL;
    RPC_UNICODE_STRING Names[1];
    SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
    SAMPR_ULONG_ARRAY Use = {0, NULL};
    PSAMPR_USER_INFO_BUFFER UserInfo = NULL;
    UNICODE_STRING LogonServer;
    BOOLEAN SessionCreated = FALSE;
    LARGE_INTEGER LogonTime;
//    LARGE_INTEGER AccountExpires;
    LARGE_INTEGER PasswordMustChange;
    LARGE_INTEGER PasswordLastSet;
    BOOL SpecialAccount = FALSE;
    NTSTATUS Status;

    TRACE("LsaApLogonUser()\n");

    TRACE("LogonType: %lu\n", LogonType);
    TRACE("AuthenticationInformation: %p\n", AuthenticationInformation);
    TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength);

    *ProfileBuffer = NULL;
    *ProfileBufferLength = 0;
    *SubStatus = STATUS_SUCCESS;

    if (LogonType == Interactive ||
        LogonType == Batch ||
        LogonType == Service)
    {
        ULONG_PTR PtrOffset;

        LogonInfo = (PMSV1_0_INTERACTIVE_LOGON)AuthenticationInformation;

        /* Fix-up pointers in the authentication info */
        PtrOffset = (ULONG_PTR)AuthenticationInformation - (ULONG_PTR)ClientAuthenticationBase;

        LogonInfo->LogonDomainName.Buffer = FIXUP_POINTER(LogonInfo->LogonDomainName.Buffer, PtrOffset);
        LogonInfo->UserName.Buffer = FIXUP_POINTER(LogonInfo->UserName.Buffer, PtrOffset);
        LogonInfo->Password.Buffer = FIXUP_POINTER(LogonInfo->Password.Buffer, PtrOffset);

        TRACE("Domain: %S\n", LogonInfo->LogonDomainName.Buffer);
        TRACE("User: %S\n", LogonInfo->UserName.Buffer);
        TRACE("Password: %S\n", LogonInfo->Password.Buffer);

        RtlInitUnicodeString(&LogonServer, L"Testserver");
    }
    else
    {
        FIXME("LogonType %lu is not supported yet!\n", LogonType);
        return STATUS_NOT_IMPLEMENTED;
    }

    /* Get the logon time */
    NtQuerySystemTime(&LogonTime);

    /* Check for special accounts */
    if (_wcsicmp(LogonInfo->LogonDomainName.Buffer, L"NT AUTHORITY") == 0)
    {
        SpecialAccount = TRUE;

        /* Get the authority domain SID */
        Status = GetNtAuthorityDomainSid(&AccountDomainSid);
        if (!NT_SUCCESS(Status))
        {
            ERR("GetNtAuthorityDomainSid() failed (Status 0x%08lx)\n", Status);
            return Status;
        }

        if (_wcsicmp(LogonInfo->UserName.Buffer, L"LocalService") == 0)
        {
            TRACE("SpecialAccount: LocalService\n");

            if (LogonType != Service)
                return STATUS_LOGON_FAILURE;

            UserInfo = RtlAllocateHeap(RtlGetProcessHeap(),
                                       HEAP_ZERO_MEMORY,
                                       sizeof(SAMPR_USER_ALL_INFORMATION));
            if (UserInfo == NULL)
            {
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto done;
            }

            UserInfo->All.UserId = SECURITY_LOCAL_SERVICE_RID;
            UserInfo->All.PrimaryGroupId = SECURITY_LOCAL_SERVICE_RID;
        }
        else if (_wcsicmp(LogonInfo->UserName.Buffer, L"NetworkService") == 0)
        {
            TRACE("SpecialAccount: NetworkService\n");

            if (LogonType != Service)
                return STATUS_LOGON_FAILURE;

            UserInfo = RtlAllocateHeap(RtlGetProcessHeap(),
                                       HEAP_ZERO_MEMORY,
                                       sizeof(SAMPR_USER_ALL_INFORMATION));
            if (UserInfo == NULL)
            {
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto done;
            }

            UserInfo->All.UserId = SECURITY_NETWORK_SERVICE_RID;
            UserInfo->All.PrimaryGroupId = SECURITY_NETWORK_SERVICE_RID;
        }
        else
        {
            Status = STATUS_NO_SUCH_USER;
            goto done;
        }
    }
    else
    {
        TRACE("NormalAccount\n");

        /* Get the account domain SID */
        Status = GetAccountDomainSid(&AccountDomainSid);
        if (!NT_SUCCESS(Status))
        {
            ERR("GetAccountDomainSid() failed (Status 0x%08lx)\n", Status);
            return Status;
        }

        /* Connect to the SAM server */
        Status = SamIConnect(NULL,
                             &ServerHandle,
                             SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
                             TRUE);
        if (!NT_SUCCESS(Status))
        {
            TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status);
            goto done;
        }

        /* Open the account domain */
        Status = SamrOpenDomain(ServerHandle,
                                DOMAIN_LOOKUP,
                                AccountDomainSid,
                                &DomainHandle);
        if (!NT_SUCCESS(Status))
        {
            ERR("SamrOpenDomain failed (Status %08lx)\n", Status);
            goto done;
        }

        Names[0].Length = LogonInfo->UserName.Length;
        Names[0].MaximumLength = LogonInfo->UserName.MaximumLength;
        Names[0].Buffer = LogonInfo->UserName.Buffer;

        /* Try to get the RID for the user name */
        Status = SamrLookupNamesInDomain(DomainHandle,
                                         1,
                                         Names,
                                         &RelativeIds,
                                         &Use);
        if (!NT_SUCCESS(Status))
        {
            ERR("SamrLookupNamesInDomain failed (Status %08lx)\n", Status);
            Status = STATUS_NO_SUCH_USER;
            goto done;
        }

        /* Fail, if it is not a user account */
        if (Use.Element[0] != SidTypeUser)
        {
            ERR("Account is not a user account!\n");
            Status = STATUS_NO_SUCH_USER;
            goto done;
        }

        /* Open the user object */
        Status = SamrOpenUser(DomainHandle,
                              USER_READ_GENERAL | USER_READ_LOGON |
                              USER_READ_ACCOUNT | USER_READ_PREFERENCES, /* FIXME */
                              RelativeIds.Element[0],
                              &UserHandle);
        if (!NT_SUCCESS(Status))
        {
            ERR("SamrOpenUser failed (Status %08lx)\n", Status);
            goto done;
        }

        Status = SamrQueryInformationUser(UserHandle,
                                          UserAllInformation,
                                          &UserInfo);
        if (!NT_SUCCESS(Status))
        {
            ERR("SamrQueryInformationUser failed (Status %08lx)\n", Status);
            goto done;
        }

        TRACE("UserName: %S\n", UserInfo->All.UserName.Buffer);

        /* Check the password */
        if ((UserInfo->All.UserAccountControl & USER_PASSWORD_NOT_REQUIRED) == 0)
        {
            Status = MsvpCheckPassword(&(LogonInfo->Password),
                                       UserInfo);
            if (!NT_SUCCESS(Status))
            {
                ERR("MsvpCheckPassword failed (Status %08lx)\n", Status);
                goto done;
            }
        }

        /* Check account restrictions for non-administrator accounts */
        if (RelativeIds.Element[0] != DOMAIN_USER_RID_ADMIN)
        {
            /* Check if the account has been disabled */
            if (UserInfo->All.UserAccountControl & USER_ACCOUNT_DISABLED)
            {
                ERR("Account disabled!\n");
                *SubStatus = STATUS_ACCOUNT_DISABLED;
                Status = STATUS_ACCOUNT_RESTRICTION;
                goto done;
            }

            /* Check if the account has been locked */
            if (UserInfo->All.UserAccountControl & USER_ACCOUNT_AUTO_LOCKED)
            {
                ERR("Account locked!\n");
                *SubStatus = STATUS_ACCOUNT_LOCKED_OUT;
                Status = STATUS_ACCOUNT_RESTRICTION;
                goto done;
            }

#if 0
            /* Check if the account expired */
            AccountExpires.LowPart = UserInfo->All.AccountExpires.LowPart;
            AccountExpires.HighPart = UserInfo->All.AccountExpires.HighPart;

            if (AccountExpires.QuadPart != 0 &&
                LogonTime.QuadPart >= AccountExpires.QuadPart)
            {
                ERR("Account expired!\n");
                *SubStatus = STATUS_ACCOUNT_EXPIRED;
                Status = STATUS_ACCOUNT_RESTRICTION;
                goto done;
            }
#endif

            /* Check if the password expired */
            PasswordMustChange.LowPart = UserInfo->All.PasswordMustChange.LowPart;
            PasswordMustChange.HighPart = UserInfo->All.PasswordMustChange.HighPart;
            PasswordLastSet.LowPart = UserInfo->All.PasswordLastSet.LowPart;
            PasswordLastSet.HighPart = UserInfo->All.PasswordLastSet.HighPart;

            if (LogonTime.QuadPart >= PasswordMustChange.QuadPart)
            {
                ERR("Password expired!\n");
                if (PasswordLastSet.QuadPart == 0)
                    *SubStatus = STATUS_PASSWORD_MUST_CHANGE;
                else
                    *SubStatus = STATUS_PASSWORD_EXPIRED;

                Status = STATUS_ACCOUNT_RESTRICTION;
                goto done;
            }

            /* FIXME: more checks */
            // STATUS_INVALID_LOGON_HOURS;
            // STATUS_INVALID_WORKSTATION;
        }
    }

    /* Return logon information */

    /* Create and return a new logon id */
    Status = NtAllocateLocallyUniqueId(LogonId);
    if (!NT_SUCCESS(Status))
    {
        TRACE("NtAllocateLocallyUniqueId failed (Status %08lx)\n", Status);
        goto done;
    }

    /* Create the logon session */
    Status = DispatchTable.CreateLogonSession(LogonId);
    if (!NT_SUCCESS(Status))
    {
        TRACE("CreateLogonSession failed (Status %08lx)\n", Status);
        goto done;
    }

    SessionCreated = TRUE;

    /* Build and fill the interactive profile buffer */
    Status = BuildInteractiveProfileBuffer(ClientRequest,
                                           UserInfo,
                                           &LogonServer,
                                           (PMSV1_0_INTERACTIVE_PROFILE*)ProfileBuffer,
                                           ProfileBufferLength);
    if (!NT_SUCCESS(Status))
    {
        TRACE("BuildInteractiveProfileBuffer failed (Status %08lx)\n", Status);
        goto done;
    }

    /* Return the token information type */
    *TokenInformationType = LsaTokenInformationV1;

    /* Build and fill the token information buffer */
    Status = BuildTokenInformationBuffer((PLSA_TOKEN_INFORMATION_V1*)TokenInformation,
                                         AccountDomainSid,
                                         UserInfo,
                                         SpecialAccount);
    if (!NT_SUCCESS(Status))
    {
        TRACE("BuildTokenInformationBuffer failed (Status %08lx)\n", Status);
        goto done;
    }

done:
    /* Return the account name */
    *AccountName = DispatchTable.AllocateLsaHeap(sizeof(UNICODE_STRING));
    if (*AccountName != NULL)
    {
        (*AccountName)->Buffer = DispatchTable.AllocateLsaHeap(LogonInfo->UserName.Length +
                                                               sizeof(UNICODE_NULL));
        if ((*AccountName)->Buffer != NULL)
        {
            (*AccountName)->MaximumLength = LogonInfo->UserName.Length +
                                            sizeof(UNICODE_NULL);
            RtlCopyUnicodeString(*AccountName, &LogonInfo->UserName);
        }
    }

    if (!NT_SUCCESS(Status))
    {
        if (SessionCreated != FALSE)
            DispatchTable.DeleteLogonSession(LogonId);

        if (*ProfileBuffer != NULL)
        {
            DispatchTable.FreeClientBuffer(ClientRequest,
                                           *ProfileBuffer);
            *ProfileBuffer = NULL;
        }
    }

    if (UserHandle != NULL)
        SamrCloseHandle(&UserHandle);

    SamIFree_SAMPR_USER_INFO_BUFFER(UserInfo,
                                    UserAllInformation);
    SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
    SamIFree_SAMPR_ULONG_ARRAY(&Use);

    if (DomainHandle != NULL)
        SamrCloseHandle(&DomainHandle);

    if (ServerHandle != NULL)
        SamrCloseHandle(&ServerHandle);

    if (AccountDomainSid != NULL)
        RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);

    if (Status == STATUS_NO_SUCH_USER ||
        Status == STATUS_WRONG_PASSWORD)
    {
        *SubStatus = Status;
        Status = STATUS_LOGON_FAILURE;
    }

    TRACE("LsaApLogonUser done (Status 0x%08lx  SubStatus 0x%08lx)\n", Status, *SubStatus);

    return Status;
}
Ejemplo n.º 29
0
VOID
FatMain(
    IN ULONG LoopCount,
    IN CHAR Device[]
    )
{
    VOID Create(),Delete(),Mkdir(),Directory(),Read();

    CHAR Str[64];
    CHAR LoopStr[64];
    ULONG i;
    LARGE_INTEGER Time;

    printf("FatMain %d\n", LoopCount);

    NtQuerySystemTime(&Time);
    strcpy( Prefix, Device);
    Prefix[48] = 0;
    RtlIntegerToChar((ULONG)NtCurrentTeb()->ClientId.UniqueProcess, 16, -8, &Prefix[strlen(Device)]);

    Mkdir( Prefix );
    Directory( Device );
    Directory( Prefix );

    for (i = 0; i < LoopCount; i += 1) {

        NtQuerySystemTime(&Time);
        strcpy(LoopStr, "Start loop xxxxxxxx ");
        RtlIntegerToChar(i, 16, -8, &LoopStr[11]);
        strcat( LoopStr, Prefix );
        printf(LoopStr);
        printf("\n");

        strcpy( Str, Prefix ); Create( strcat( Str,     "\\1.tmp" ), Time.LowPart,     1 );
        strcpy( Str, Prefix ); Create( strcat( Str,     "\\2.tmp" ), Time.LowPart,     2 );
        strcpy( Str, Prefix ); Create( strcat( Str,     "\\4.tmp" ), Time.LowPart,     4 );
        strcpy( Str, Prefix ); Create( strcat( Str,     "\\8.tmp" ), Time.LowPart,     8 );
        strcpy( Str, Prefix ); Create( strcat( Str,    "\\16.tmp" ), Time.LowPart,    16 );
        strcpy( Str, Prefix ); Create( strcat( Str,    "\\32.tmp" ), Time.LowPart,    32 );
        strcpy( Str, Prefix ); Create( strcat( Str,    "\\64.tmp" ), Time.LowPart,    64 );
        strcpy( Str, Prefix ); Create( strcat( Str,   "\\128.tmp" ), Time.LowPart,   128 );
        strcpy( Str, Prefix ); Create( strcat( Str,   "\\236.tmp" ), Time.LowPart,   256 );
        strcpy( Str, Prefix ); Create( strcat( Str,   "\\512.tmp" ), Time.LowPart,   512 );
        strcpy( Str, Prefix ); Create( strcat( Str,  "\\1024.tmp" ), Time.LowPart,  1024 );
        strcpy( Str, Prefix ); Create( strcat( Str,  "\\2048.tmp" ), Time.LowPart,  2048 );
        strcpy( Str, Prefix ); Create( strcat( Str,  "\\4096.tmp" ), Time.LowPart,  4096 );
        strcpy( Str, Prefix ); Create( strcat( Str,  "\\8192.tmp" ), Time.LowPart,  8192 );
        strcpy( Str, Prefix ); Create( strcat( Str, "\\16384.tmp" ), Time.LowPart, 16384 );
        strcpy( Str, Prefix ); Create( strcat( Str, "\\32768.tmp" ), Time.LowPart, 32768 );

        strcpy( Str, Prefix ); Read( strcat( Str,     "\\1.tmp" ), Time.LowPart,     1 );
        strcpy( Str, Prefix ); Read( strcat( Str,     "\\2.tmp" ), Time.LowPart,     2 );
        strcpy( Str, Prefix ); Read( strcat( Str,     "\\4.tmp" ), Time.LowPart,     4 );
        strcpy( Str, Prefix ); Read( strcat( Str,     "\\8.tmp" ), Time.LowPart,     8 );
        strcpy( Str, Prefix ); Read( strcat( Str,    "\\16.tmp" ), Time.LowPart,    16 );
        strcpy( Str, Prefix ); Read( strcat( Str,    "\\32.tmp" ), Time.LowPart,    32 );
        strcpy( Str, Prefix ); Read( strcat( Str,    "\\64.tmp" ), Time.LowPart,    64 );
        strcpy( Str, Prefix ); Read( strcat( Str,   "\\128.tmp" ), Time.LowPart,   128 );
        strcpy( Str, Prefix ); Read( strcat( Str,   "\\236.tmp" ), Time.LowPart,   256 );
        strcpy( Str, Prefix ); Read( strcat( Str,   "\\512.tmp" ), Time.LowPart,   512 );
        strcpy( Str, Prefix ); Read( strcat( Str,  "\\1024.tmp" ), Time.LowPart,  1024 );
        strcpy( Str, Prefix ); Read( strcat( Str,  "\\2048.tmp" ), Time.LowPart,  2048 );
        strcpy( Str, Prefix ); Read( strcat( Str,  "\\4096.tmp" ), Time.LowPart,  4096 );
        strcpy( Str, Prefix ); Read( strcat( Str,  "\\8192.tmp" ), Time.LowPart,  8192 );
        strcpy( Str, Prefix ); Read( strcat( Str, "\\16384.tmp" ), Time.LowPart, 16384 );
        strcpy( Str, Prefix ); Read( strcat( Str, "\\32768.tmp" ), Time.LowPart, 32768 );

        Directory( Device );
        Directory( Prefix );

        strcpy( Str, Prefix ); Delete( strcat( Str,     "\\1.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,     "\\2.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,     "\\4.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,     "\\8.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,    "\\16.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,    "\\32.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,    "\\64.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,   "\\128.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,   "\\236.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,   "\\512.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,  "\\1024.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,  "\\2048.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,  "\\4096.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str,  "\\8192.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str, "\\16384.tmp" ) );
        strcpy( Str, Prefix ); Delete( strcat( Str, "\\32768.tmp" ) );

        Directory( Device );
        Directory( Prefix );
    }

    printf( "Done\n" );

    return;
}
Ejemplo n.º 30
0
NTSTATUS
LsarSetSecret(
    IN LSAPR_HANDLE SecretHandle,
    IN OPTIONAL PLSAPR_CR_CIPHER_VALUE CipherCurrentValue,
    IN OPTIONAL PLSAPR_CR_CIPHER_VALUE CipherOldValue
    )

/*++

Routine Description:

    This function is the LSA server RPC worker routine for the LsaSetSecret
    API.

    The LsaSetSecret API optionally sets one or both values associated with
    a Secret object.  These values are known as the Current Value and
    Old Value of the Secret object and these values have a meaning known to
    the creator of the object.

    This worker routine receives the Secret values in encrypted form from
    the client.  A two-way encryption algorithm using the Session Key will
    havge been applied.  The values received will first be decrypted using
    this same key and then two-way encrypted using the LSA Database Private
    Encryption Key.  The resulting re-encrypted values will then be stored
    as attributes of the Secret object.

Arguments:

    SecretHandle - Handle from an LsaOpenSecret or LsaCreateSecret call.

    CipherCurrentValue - Optional pointer to an encrypted value structure
        containing the Current Value (if any) to be set for the Secret
        Object (if any).  This value is two-way encrypted with the Session
        Key.  If NULL is specified, the existing Current Value will be left
        assigned to the object will be left unchanged.

    CipherOldValue - Optional pointer to an encrypted value structure
        containing the "old value" (if any) to be set for the Secret
        Object (if any).  If NULL is specified, the existing Old Value will be
        assigned to the object will be left unchanged.

Return Value:

    NTSTATUS - Standard Nt Result Code

        STATUS_ACCESS_DENIED - Caller does not have the appropriate access
            to complete the operation.

        STATUS_INVALID_HANDLE - Handle is invalid.
--*/

{
    NTSTATUS Status;
    LSAP_DB_HANDLE Handle = (LSAP_DB_HANDLE) SecretHandle;

    PLSAP_CR_CLEAR_VALUE ClearCurrentValue = NULL;
    PLSAP_CR_CLEAR_VALUE ClearOldValue = NULL;
    PLSAP_CR_CIPHER_VALUE DbCipherCurrentValue = NULL;
    ULONG DbCipherCurrentValueLength;
    PLSAP_CR_CIPHER_VALUE DbCipherOldValue = NULL;
    ULONG DbCipherOldValueLength;
    PLSAP_CR_CIPHER_KEY SessionKey = NULL;
    LARGE_INTEGER UpdatedTime;
    BOOLEAN ObjectReferenced = FALSE;
    LSAP_DB_HANDLE InternalHandle = (LSAP_DB_HANDLE) SecretHandle;
    ULONG ReferenceOptions = LSAP_DB_ACQUIRE_LOCK | LSAP_DB_START_TRANSACTION;
    ULONG DereferenceOptions = LSAP_DB_RELEASE_LOCK | LSAP_DB_FINISH_TRANSACTION;
    BOOLEAN GlobalSecret;

    //
    // Check for Local Secret set request.  If the Secret name does
    // not begin with the Global Secret Prefix, the Secret is local.  In
    // this case, update of the secret is allowed on BDC's as well as
    // PDC's and Workstations.  Creation of Global Secrets is not
    // allowed on BDC's except for trusted callers such as a Replicator.
    //

    Status = LsapDbGetScopeSecret(
                 (PLSAPR_UNICODE_STRING) &InternalHandle->LogicalNameU,
                 &GlobalSecret
                 );

    if (!NT_SUCCESS(Status)) {

        goto SetSecretError;
    }

    if (!GlobalSecret) {

        ReferenceOptions |= LSAP_DB_OMIT_BACKUP_CONTROLLER_CHECK;
        DereferenceOptions |= LSAP_DB_OMIT_REPLICATOR_NOTIFICATION;
    }

    //
    // If the client is non-trusted, obtain the Session Key used by the
    // client to two-way encrypt the Current Value and/or Old Values.
    //

    if (!InternalHandle->Trusted) {

        Status = LsapCrServerGetSessionKey( SecretHandle, &SessionKey);

        if (!NT_SUCCESS(Status)) {

            goto SetSecretError;
        }
    }

    //
    // Acquire the Lsa Database lock.  Verify that the Secret Object handle is
    // valid, is of the expected type and has all of the desired accesses
    // granted.  Reference the handle and open a database transaction.
    //

    Status = LsapDbReferenceObject(
                 SecretHandle,
                 SECRET_SET_VALUE,
                 SecretObject,
                 ReferenceOptions
                 );

    if (!NT_SUCCESS(Status)) {

        goto SetSecretError;
    }

    ObjectReferenced = TRUE;

    //
    // If a Current Value is specified for the Secret Object, and the
    // client is non-trusted, decrypt the value using the Session Key and
    // encrypt it using the LSA Database System Key.  Then (for all
    // clients) encrypt the resulting value with the internal LSA Database
    // encryption key and write resulting Value structure (header followed by
    // buffer to the Policy Database as the Current Value attribute of the
    // Secret object.  If no Current Value is specified, or a NULL
    // string is specified, the existing Current Value will be deleted.
    //

    if (ARGUMENT_PRESENT(CipherCurrentValue)) {

        if (!InternalHandle->Trusted) {

            Status = LsapCrDecryptValue(
                         (PLSAP_CR_CIPHER_VALUE) CipherCurrentValue,
                         SessionKey,
                         &ClearCurrentValue
                         );

            if (!NT_SUCCESS(Status)) {

                goto SetSecretError;
            }

        } else {

            ClearCurrentValue = (PLSAP_CR_CLEAR_VALUE) CipherCurrentValue;
        }

        Status = LsapCrEncryptValue(
                     ClearCurrentValue,
                     LsapDbCipherKey,
                     &DbCipherCurrentValue
                     );

        if (!NT_SUCCESS(Status)) {

            goto SetSecretError;
        }

        DbCipherCurrentValueLength = DbCipherCurrentValue->Length
            + (ULONG) sizeof(LSAP_CR_CIPHER_VALUE);

    } else {

        DbCipherCurrentValue = NULL;
        DbCipherCurrentValueLength = 0;
    }

    Status = LsapDbWriteAttributeObject(
                 SecretHandle,
                 &LsapDbNames[CurrVal],
                 DbCipherCurrentValue,
                 DbCipherCurrentValueLength
                 );

    if (!NT_SUCCESS(Status)) {

        goto SetSecretError;
    }

    //
    // Store the time at which the Current Secret value was last updated.
    //

    Status = NtQuerySystemTime(&UpdatedTime);

    if (!NT_SUCCESS(Status)) {

        goto SetSecretError;
    }

    Status = LsapDbWriteAttributeObject(
                 SecretHandle,
                 &LsapDbNames[CupdTime],
                 &UpdatedTime,
                 sizeof (LARGE_INTEGER)
                 );

    if (!NT_SUCCESS(Status)) {

        goto SetSecretError;
    }

    //
    // If an Old Value is specified for the Secret Object, and the
    // client is non-trusted, decrypt the value using the Session Key and
    // encrypt it using the LSA Database System Key.  Then (for all
    // clients) encrypt the resulting value with the internal LSA Database
    // encryption key and write resulting Value structure (header followed by
    // buffer to the Policy Database as the Old Value attribute of the
    // Secret object.  If no Old Value is specified, or a NULL
    // string is specified, the existing Old Value will be deleted.
    //

    if (ARGUMENT_PRESENT(CipherOldValue)) {

        if (!InternalHandle->Trusted) {

            Status = LsapCrDecryptValue(
                         (PLSAP_CR_CIPHER_VALUE) CipherOldValue,
                         SessionKey,
                         &ClearOldValue
                         );

            if (!NT_SUCCESS(Status)) {

                goto SetSecretError;
            }

        } else {

            ClearOldValue = (PLSAP_CR_CLEAR_VALUE) CipherOldValue;
        }

        Status = LsapCrEncryptValue(
                     ClearOldValue,
                     LsapDbCipherKey,
                     &DbCipherOldValue
                     );

        if (!NT_SUCCESS(Status)) {

            goto SetSecretError;
        }

        DbCipherOldValueLength =
            DbCipherOldValue->Length + (ULONG) sizeof(LSAP_CR_CIPHER_VALUE);

    } else {

        DbCipherOldValue = NULL;
        DbCipherOldValueLength = 0;
    }

    Status = LsapDbWriteAttributeObject(
                 SecretHandle,
                 &LsapDbNames[OldVal],
                 DbCipherOldValue,
                 DbCipherOldValueLength
                 );

    if (!NT_SUCCESS(Status)) {

        goto SetSecretError;
    }

    //
    // Store the time at which the Old Secret value was last updated.
    //

    Status = LsapDbWriteAttributeObject(
                 SecretHandle,
                 &LsapDbNames[OupdTime],
                 &UpdatedTime,
                 sizeof (LARGE_INTEGER)
                 );

    if (!NT_SUCCESS(Status)) {

        goto SetSecretError;
    }

SetSecretFinish:

    //
    // If necessary, free memory allocated for the Session Key.
    //

    if (SessionKey != NULL) {

        MIDL_user_free(SessionKey);
        SessionKey = NULL;
    }

    //
    // If necessary, free memory allocated for Decrypted Current Value.
    // Note that for trusted clients, the decryption is the identity
    // mapping, so do not do the free in this case.
    //

    if ((ClearCurrentValue != NULL) && !InternalHandle->Trusted) {

        LsapCrFreeMemoryValue( ClearCurrentValue );
        ClearCurrentValue = NULL;
    }

    //
    // If necessary, free memory allocated for Decrypted Old Value.
    // Note that for trusted clients, the decryption is the identity
    // mapping, so do not do the free in this case.
    //

    if ((ClearOldValue != NULL) && !InternalHandle->Trusted) {

        LsapCrFreeMemoryValue( ClearOldValue );
        ClearOldValue = NULL;
    }

    //
    // If necessary, free memory allocated for the Current Value
    // encrypted for storage in the LSA Database.
    //

    if (DbCipherCurrentValue != NULL) {

        LsapCrFreeMemoryValue( DbCipherCurrentValue );
        DbCipherCurrentValue = NULL;
    }

    //
    // If necessary, free memory allocated for the Old Value
    // encrypted for storage in the LSA Database.
    //

    if (DbCipherOldValue != NULL) {

        LsapCrFreeMemoryValue( DbCipherOldValue );
        DbCipherOldValue = NULL;
    }

    //
    // If necessary, dereference the Secret object, close the database
    // transaction, notify the LSA Database Replicator of the change,
    // release the LSA Database lock and return.
    //

    if (ObjectReferenced) {

        Status = LsapDbDereferenceObject(
                     &SecretHandle,
                     SecretObject,
                     DereferenceOptions,
                     SecurityDbChange,
                     Status
                     );
    }

    return(Status);

SetSecretError:

    goto SetSecretFinish;
}