Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: C++ XE6, Windows 10 64 bits, How to use SetSystemTime



Permlink Replies: 13 - Last Post: Nov 23, 2017 8:01 AM Last Post By: Gilbert Pasqual... Threads: [ Previous | Next ]
Gilbert Pasqual...

Posts: 12
Registered: 12/23/00
C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 9, 2017 3:04 AM
I would change the time of the system.
I try it with SetSystemTime() :

{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;

// Get a token for this process.

if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
Memo1->Lines->Add("Erreur OpenProcessToken");

// Get the LUID for the SystemTime privilege.
LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid);

tkp.PrivilegeCount = 1; // one privilege to set
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

if ( !AdjustTokenPrivileges( hToken, FALSE, &tkp,sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) )
Memo1->Lines->Add("Erreur AdjustTokenPrivileges : " + UnicodeString(GetLastError()));

SYSTEMTIME st, lt;

GetSystemTime(&st);

i f (!SetSystemTime(&st))
{
Memo1->Lines->Add("SetSystemTime() failed " + UnicodeString(GetLastError()));
}
}

I have allways

"SetSystemTime() failed 1314"

What I have to change ?
Thanks

Remy Lebeau (Te...


Posts: 8,839
Registered: 12/23/01
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 9, 2017 8:58 AM   in response to: Gilbert Pasqual... in response to: Gilbert Pasqual...
Gilbert Pasqualini wrote:

I would change the time of the system.

Are you running your code as an admin user with elevated rights? Only
an admin can change the system time.

I have allways

"SetSystemTime() failed 1314"

1314 is ERROR_PRIVILEGE_NOT_HELD.

And FYI, you don't need to adjust token privileges manually when using
SetSystemTime(). The documentation says so:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms724942.aspx

The calling process must have the SE_SYSTEMTIME_NAME privilege. This
privilege is disabled by default. **The SetSystemTime function enables
the SE_SYSTEMTIME_NAME privilege before changing the system time and
disables the privilege before returning**.

--
Remy Lebeau (TeamB)
Gilbert Pasqual...

Posts: 12
Registered: 12/23/00
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 10, 2017 9:11 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Gilbert Pasqualini wrote:

I would change the time of the system.

Are you running your code as an admin user with elevated rights? Only
an admin can change the system time.

I have allways

"SetSystemTime() failed 1314"

1314 is ERROR_PRIVILEGE_NOT_HELD.

And FYI, you don't need to adjust token privileges manually when using
SetSystemTime(). The documentation says so:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms724942.aspx

The calling process must have the SE_SYSTEMTIME_NAME privilege. This
privilege is disabled by default. **The SetSystemTime function enables
the SE_SYSTEMTIME_NAME privilege before changing the system time and
disables the privilege before returning**.

--
Remy Lebeau (TeamB)

If I run asAdministrator there no more error.

How understand :

"The calling process must have the SE_SYSTEMTIME_NAME privilege.
This privilege is disabled by default. **
The SetSystemTime function enables the SE_SYSTEMTIME_NAME privilege before changing the system time
and disables the privilege before returning**".
Remy Lebeau (Te...


Posts: 8,839
Registered: 12/23/01
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 10, 2017 11:18 AM   in response to: Gilbert Pasqual... in response to: Gilbert Pasqual...
Gilbert Pasqualini wrote:

If I run asAdministrator there no more error.

As expected.

So, you will have to either:

1. run your entire app elevated as an admin.

2. separate out the SetSystemTime() call to a block of code that can be
run in its own process or COM object, and then run that code elevated
as an admin.

3. grant permission to change the system time to non-admin users.

"The calling process must have the SE_SYSTEMTIME_NAME privilege.

Yes, but the user that runs your app has to have that privilege
present in their security token before the app can enable the
privilege in code. AdustTokenPrivileges() doesn't add new privileges
to a token, it only toggles the state of pre-existing privileges.

SE_SYSTEMTIME_NAME is only present for admin users by default, which
is why SetSystemTime() fails when a non-admin user runs your app.

Your code only logs fatal errors from AdjustTokenPrivileges(). But
it ignores the fact that SE_SYSTEMTIME_NAME may not have been present
at all. If SE_SYSTEMTIME_NAME is not present in the token,
AdjustTokenPrivileges() succeeds, not fails, but GetLastError() returns
ERROR_NOT_ALL_ASSIGNED to indicate that the privilege was not present
and thus not adjusted. This is clearly stated in the documentation:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa375202.aspx

Your code doesn't take that possibility into account.

Try something more like this:

bool TMyForm::SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, bool
bEnablePrivilege)
{
    LUID luid;
    if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid) )
    {
        Memo1->Lines->Add(_D("Erreur LookupPrivilegeValue : ") +
String(GetLastError()));
        return false;
    }
 
    TOKEN_PRIVILEGES tp;
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = bEnablePrivilege ?
SE_PRIVILEGE_ENABLED : 0;
 
    if (!AdjustTokenPrivileges(hToken, FALSE, &tp,
sizeof(TOKEN_PRIVILEGES), NULL, NULL) )
    { 
        Memo1->Lines->Add(_D("Erreur AdjustTokenPrivileges : ") +
String(GetLastError()));
        return false; 
    } 
 
    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
    {
        Memo1->Lines->Add(_D("Le jeton n'a pas le privilège ") +
String(lpszPrivilege));
        return false;
    } 
 
    return true;
}
 
{
    HANDLE hToken;
    if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        Memo1->Lines->Add(_D("Erreur OpenProcessToken :") +
String(GetLastError()));
    }
    else
    {
        if (SetPrivilege(hToken, SE_SYSTEMTIME_NAME, true) )
        {
            SYSTEMTIME st;
            GetSystemTime(&st);
 
            if (!SetSystemTime(&st))
            {
                Memo1->Lines->Add("Erreur SetSystemTime : " +
String(GetLastError()));
            }
        }
 
        CloseHandle(hToken);
    }
}


Or, simply ignore the token adjustment, since SetSystemTime() already
does it for you:

{
    SYSTEMTIME st;
    GetSystemTime(&st);
 
    if (!SetSystemTime(&st))
    {
        if (GetLastError() == ERROR__PRIVILEGE_NOT_HELD)
            Memo1->Lines->Add(_D("Vous n'avez pas la permission de
régler l'heure système"));
        else
            Memo1->Lines->Add("Erreur SetSystemTime() : " +
String(GetLastError()));
    }
}


--
Remy Lebeau (TeamB)
Gilbert Pasqual...

Posts: 12
Registered: 12/23/00
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 11, 2017 8:52 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Gilbert Pasqualini wrote:

If I run asAdministrator there no more error.

As expected.

So, you will have to either:

1. run your entire app elevated as an admin.

2. separate out the SetSystemTime() call to a block of code that can be
run in its own process or COM object, and then run that code elevated
as an admin.

3. grant permission to change the system time to non-admin users.

"The calling process must have the SE_SYSTEMTIME_NAME privilege.

Yes, but the user that runs your app has to have that privilege
present in their security token before the app can enable the
privilege in code. AdustTokenPrivileges() doesn't add new privileges
to a token, it only toggles the state of pre-existing privileges.

SE_SYSTEMTIME_NAME is only present for admin users by default, which
is why SetSystemTime() fails when a non-admin user runs your app.

Your code only logs fatal errors from AdjustTokenPrivileges(). But
it ignores the fact that SE_SYSTEMTIME_NAME may not have been present
at all. If SE_SYSTEMTIME_NAME is not present in the token,
AdjustTokenPrivileges() succeeds, not fails, but GetLastError() returns
ERROR_NOT_ALL_ASSIGNED to indicate that the privilege was not present
and thus not adjusted. This is clearly stated in the documentation:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa375202.aspx

Your code doesn't take that possibility into account.

Try something more like this:

bool TMyForm::SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, bool
bEnablePrivilege)
{
    LUID luid;
    if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid) )
    {
        Memo1->Lines->Add(_D("Erreur LookupPrivilegeValue : ") +
String(GetLastError()));
        return false;
    }
 
    TOKEN_PRIVILEGES tp;
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = bEnablePrivilege ?
SE_PRIVILEGE_ENABLED : 0;
 
    if (!AdjustTokenPrivileges(hToken, FALSE, &tp,
sizeof(TOKEN_PRIVILEGES), NULL, NULL) )
    { 
        Memo1->Lines->Add(_D("Erreur AdjustTokenPrivileges : ") +
String(GetLastError()));
        return false; 
    } 
 
    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
    {
        Memo1->Lines->Add(_D("Le jeton n'a pas le privilège ") +
String(lpszPrivilege));
        return false;
    } 
 
    return true;
}
 
{
    HANDLE hToken;
    if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        Memo1->Lines->Add(_D("Erreur OpenProcessToken :") +
String(GetLastError()));
    }
    else
    {
        if (SetPrivilege(hToken, SE_SYSTEMTIME_NAME, true) )
        {
            SYSTEMTIME st;
            GetSystemTime(&st);
 
            if (!SetSystemTime(&st))
            {
                Memo1->Lines->Add("Erreur SetSystemTime : " +
String(GetLastError()));
            }
        }
 
        CloseHandle(hToken);
    }
}

I have the message

Le jeton n'a pas le privilège SeSystemtimePrivilege

Or, simply ignore the token adjustment, since SetSystemTime() already
does it for you:

{
    SYSTEMTIME st;
    GetSystemTime(&st);
 
    if (!SetSystemTime(&st))
    {
        if (GetLastError() == ERROR__PRIVILEGE_NOT_HELD)
            Memo1->Lines->Add(_D("Vous n'avez pas la permission de
régler l'heure système"));
        else
            Memo1->Lines->Add("Erreur SetSystemTime() : " +
String(GetLastError()));
    }
}

I have the message :
Vous n'avez pas la permission de régler l'Heure system

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 8,839
Registered: 12/23/01
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 13, 2017 10:04 AM   in response to: Gilbert Pasqual... in response to: Gilbert Pasqual...
Gilbert Pasqualini wrote:

I have the message

Le jeton n'a pas le privilège SeSystemtimePrivilege

That means AdjustTokenPrivileges() is not finding the
SE_SYSTEMTIME_NAME privilege in the user token.

I have the message :

Vous n'avez pas la permission de régler l'Heure system

Same as above.

Your code is running under a user account that simply is not allowed to
change the system time. Period. You will have to use a different user
account that is allowed to.

--
Remy Lebeau (TeamB)
Gilbert Pasqual...

Posts: 12
Registered: 12/23/00
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 14, 2017 3:24 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Gilbert Pasqualini wrote:

I have the message

Le jeton n'a pas le privilège SeSystemtimePrivilege

That means AdjustTokenPrivileges() is not finding the
SE_SYSTEMTIME_NAME privilege in the user token.

I have the message :

Vous n'avez pas la permission de régler l'Heure system

Same as above.

Your code is running under a user account that simply is not allowed to
change the system time. Period. You will have to use a different user
account that is allowed to.

--
Remy Lebeau (TeamB)

Thanks.
What do you think of settime and setdate ?
Gilbert Pasqual...

Posts: 12
Registered: 12/23/00
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 14, 2017 8:41 AM   in response to: Gilbert Pasqual... in response to: Gilbert Pasqual...
Gilbert Pasqualini wrote:
Remy Lebeau (TeamB) wrote:
Gilbert Pasqualini wrote:

I have the message

Le jeton n'a pas le privilège SeSystemtimePrivilege

That means AdjustTokenPrivileges() is not finding the
SE_SYSTEMTIME_NAME privilege in the user token.

I have the message :

Vous n'avez pas la permission de régler l'Heure system

Same as above.

Your code is running under a user account that simply is not allowed to
change the system time. Period. You will have to use a different user
account that is allowed to.

--
Remy Lebeau (TeamB)

Thanks.
What do you think of settime and setdate ?
I try to use settime.

To chage the time it is nessery to be a Administrator, like for SetSystemTime.
Remy Lebeau (Te...


Posts: 8,839
Registered: 12/23/01
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 14, 2017 9:59 AM   in response to: Gilbert Pasqual... in response to: Gilbert Pasqual...
Gilbert Pasqualini wrote:

What do you think of settime and setdate ?

What about them? There are no such functions in the RTL, VCL/FMX, or
Win32 API. You will have to be more specific.

--
Remy Lebeau (TeamB)
Gilbert Pasqual...

Posts: 12
Registered: 12/23/00
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 15, 2017 2:50 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Gilbert Pasqualini wrote:

What do you think of settime and setdate ?

What about them? There are no such functions in the RTL, VCL/FMX, or
Win32 API. You will have to be more specific.

--
Remy Lebeau (TeamB)

With "include <Dos.h>", the functions exist.
I used them, but I found it was necessery to be an Admistrator for the 2 functions settime and setdate.
Finally for SetSystemTime or settime or setdate only one solution : to be an Admistrator.

Thank you very much for helping me, or if you prefer "Merci beaucoup" Remy (Gambit ?)
Remy Lebeau (Te...


Posts: 8,839
Registered: 12/23/01
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 15, 2017 10:39 AM   in response to: Gilbert Pasqual... in response to: Gilbert Pasqual...
Gilbert Pasqualini wrote:

With "include <Dos.h>", the functions exist.

You are referring to C runtime functions. On Windows, those are
implemented by Embarcadero using the Win32 API SetLocalTime() function
(see $(BDS)\source\cpprtl\Source\time\dossdate.c), which has the same
SE_SYSTEMTIME_NAME requirement as SetSystemTime() (the former sets the
clock using the local timezone, the latter sets the clock using UTC).

I used them, but I found it was necessery to be an Admistrator for
the 2 functions settime and setdate. Finally for SetSystemTime or
settime or setdate only one solution : to be an Admistrator.

Yup. Or have an admin grant "Change the system time" permission to
non-admin users.

Remy (Gambit ?)

Yup.

--
Remy Lebeau (TeamB)
Gilbert Pasqual...

Posts: 12
Registered: 12/23/00
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 16, 2017 7:53 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Gilbert Pasqualini wrote:

With "include <Dos.h>", the functions exist.

You are referring to C runtime functions. On Windows, those are
implemented by Embarcadero using the Win32 API SetLocalTime() function
(see $(BDS)\source\cpprtl\Source\time\dossdate.c), which has the same
SE_SYSTEMTIME_NAME requirement as SetSystemTime() (the former sets the
clock using the local timezone, the latter sets the clock using UTC).

I used them, but I found it was necessery to be an Admistrator for
the 2 functions settime and setdate. Finally for SetSystemTime or
settime or setdate only one solution : to be an Admistrator.

Yup. Or have an admin grant "Change the system time" permission to
non-admin users.

It seems we dit not foud a way to grant permission to non-administrator users.

Remy (Gambit ?)

Yup.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 8,839
Registered: 12/23/01
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 16, 2017 1:23 PM   in response to: Gilbert Pasqual... in response to: Gilbert Pasqual...
Gilbert Pasqualini wrote:

It seems we dit not foud a way to grant permission to
non-administrator users.

You have to use a System/Group Policy editor, which are available in
Professional and higher editions of Windows (not the Home edition):

https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/529.mspx

https://technet.microsoft.com/en-us/library/dn221970.aspx

https://docs.microsoft.com/en-us/windows/device-security/security-policy-settings/change-the-system-time

--
Remy Lebeau (TeamB)
Gilbert Pasqual...

Posts: 12
Registered: 12/23/00
Re: C++ XE6, Windows 10 64 bits, How to use SetSystemTime
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 23, 2017 8:01 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Gilbert Pasqualini wrote:

It seems we dit not foud a way to grant permission to
non-administrator users.

You have to use a System/Group Policy editor, which are available in
Professional and higher editions of Windows (not the Home edition):

https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/529.mspx

https://technet.microsoft.com/en-us/library/dn221970.aspx

https://docs.microsoft.com/en-us/windows/device-security/security-policy-settings/change-the-system-time

--
Remy Lebeau (TeamB)

I apologise, I am not be ablle to connect to the Forum.
I thank you for your last answers.
For the moment I use the "Run as an Administrator".
May be later I will try your last proposals.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02