Announcement

Collapse
No announcement yet.

Win32api.inc quirk - LookupPrivilegeValue and large_integer type

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Win32api.inc quirk - LookupPrivilegeValue and large_integer type

    In the latest win32api.inc file is this declaration:
    DECLARE FUNCTION LookupPrivilegeValue LIB "ADVAPI32.DLL" ALIAS "LookupPrivilegeValueA" (lpSystemName AS ASCIIZ, lpName AS ASCIIZ, lpLuid AS QUAD) AS LONG

    From a recent thread on this forum the conclusion was that it should be:
    DECLARE FUNCTION LookupPrivilegeValue LIB "ADVAPI32.DLL" ALIAS "LookupPrivilegeValueA" (lpSystemName AS ASCIIZ, lpName AS ASCIIZ, lpLuid AS LARGE_INTEGER) AS LONG
    And if that's the case then the current win32api.inc is missing the declaration for LARGE_INTEGER:
    TYPE LARGE_INTEGER
    lowpart AS LONG
    highpart AS LONG
    END TYPE



    (Can't compile half of Semens code without that )


    ------------------
    -

  • #2
    LARGE_INTEGER is approximately equivalent to a QUAD-integer, and since PowerBASIC directly supports QUAD-integers it seems that using one is the best choice.

    If you need to break the QUAD apart, then either use a UNION, the UDT you describe (and is now deemed redundant), or use pointers to access the two halves of the QUAD-integer.


    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>
    Lance
    mailto:[email protected]

    Comment


    • #3
      > LARGE_INTEGER is approximately equivalent to a QUAD-integer

      It's necessary to ask Microsoft to rewrite MSDN.
      Code:
      BOOL LookupPrivilegeValue(
        LPCTSTR lpSystemName,  // system name
        LPCTSTR lpName,        // privilege name
        PLUID lpLuid           // locally unique identifier
      );
      MSDN do not use "LARGE_INTEGER" (unlike this is the same).

      If you change LUID to QUAD, why do you leave TYPE LUID ?
      Where is a logic ?

      ------------------
      E-MAIL: [email protected]

      Comment


      • #4
        Possibly because a famous Russian programmer may still actually *want* to use a LUID structure for some reason... For the rest of us that just want to retrieve the parameter and possibly pass it to another API (without actually dealing with it's content), then a QUAD-integer is as suitable as any 8-byte block.

        Basically, the WIN32API.INC file is not "set in stone" and compusory to use - you are free to modify and adapt it's equates, declarations and structures to suit your own purposes. If you don't like our translation, edit your copy!

        ------------------
        Lance
        PowerBASIC Support
        mailto:[email protected][email protected]</A>
        Lance
        mailto:[email protected]

        Comment


        • #5
          The following is the C/C++ definition:

          Code:
          The LARGE_INTEGER structure is used to represent a 64-bit signed
          integer value. 
          
          typedef union _LARGE_INTEGER { 
              struct {
                  DWORD LowPart; 
                  LONG  HighPart; 
              };
              LONGLONG QuadPart;
          } LARGE_INTEGER;
          Members

          LowPart
          Specifies the low-order 32 bits.
          HighPart
          Specifies the high-order 32 bits.
          QuadPart
          Specifies a 64-bit signed integer.

          Remarks
          The LARGE_INTEGER structure is actually a union. If your compiler
          has built-in support for 64-bit integers, use the QuadPart
          member to store the 64-bit integer. Otherwise, use the LowPart
          and HighPart members to store the 64-bit integer.

          Lance's point is right on!!!!!!!

          Also:

          An LUID is a 64-bit value guaranteed to be unique only on the
          system on which it was generated. The uniqueness of a locally
          unique identifier (LUID) is guaranteed only until the system
          is restarted.

          An LUID is not for direct manipulation. Applications are to use
          functions and structures to manipulate LUID values.

          typedef LARGE_INTEGER LUID

          The LUID is typedefed to a LARGE_INTEGER for convienence.

          Cheers,
          Cecil

          ------------------


          [This message has been edited by Cecil Williams (edited August 13, 2001).]

          Comment


          • #6
            Cecil & Lance --
            Again, I don't doubt that Luid = QUAD.
            But if to declare x As Quad, how to fill Privileges in TOKEN_PRIVILEGES ?
            From current Win32Api:
            Code:
            TYPE LUID
              LowPart AS DWORD
              HighPart AS LONG
            END TYPE
            
            TYPE LUID_AND_ATTRIBUTES
              pLuid AS LUID
              Attributes AS DWORD
            END TYPE
            
            TYPE TOKEN_PRIVILEGES
              PrivilegeCount AS DWORD
              Privileges(0 TO 0) AS LUID_AND_ATTRIBUTES ' array size may vary
            END TYPE
            If to declare x As Luid, it's necessary to use ByVal VarPtr(x) in LookupPrivilegeValue.
            For what purpose it was necessary to change Jule's declaration ?
            It was incorrect ?

            I know that I can edit Win32Api.Inc by myself. But it's not an argument -
            new releases of Win32Api have new declarations and - de-facto - no choice.

            ------------------
            E-MAIL: [email protected]

            Comment


            • #7
              Hi

              personally I think one is better served by declaring TOKEN_PRIVILEGES
              as follows:

              Code:
              TYPE T_TOKEN_PRIVILEGES
                PrivilegeCount AS DWORD
                Privileges AS BYTE PTR ' array size may vary
              END TYPE
               
              #IF NOT %DEF(%TOKEN_ADJUST_PRIVILEGES)
              %TOKEN_ADJUST_PRIVILEGES = &H0020
              #ENDIF
               
              #IF NOT %DEF(%TOKEN_QUERY)
              %TOKEN_QUERY = &H0008
              #ENDIF
                                    
              'example usage
              FUNCTION enableprivs() AS LONG
                  LOCAL hToken AS LONG
                  LOCAL tToken AS T_TOKEN_PRIVILEGES
                  DIM tLuid(0:1) AS LUID_AND_ATTRIBUTES
                   
                  tToken.Privileges = VARPTR(tLuid(0))
               
                  IF ISFALSE( OpenProcessToken( GetCurrentProcess(), _
                                                  %TOKEN_ADJUST_PRIVILEGES OR %TOKEN_QUERY, _
                                                  hToken ) )  THEN
                      FUNCTION = %FALSE
                      GOTO Clean_Up
                  END IF
               
                  ' enable SeBackupPrivilege, SeRestorePrivilege
                  IF ISFALSE( LookUpPrivilegeValue( BYVAL %NULL, $SE_BACKUP_NAME, BYVAL VARPTR(tLuid(0)) ) ) THEN
                      FUNCTION = %FALSE
                      GOTO Clean_Up
                  END IF
               
                  IF ISFALSE( LookUpPrivilegeValue( BYVAL %NULL, $SE_RESTORE_NAME, BYVAL VARPTR(tLuid(1)) ) ) THEN
                      FUNCTION = %FALSE
                      GOTO Clean_Up
                  END IF
               
                  tToken.PrivilegeCount = 2
                  tLuid(0).Attributes = %SE_PRIVILEGE_ENABLED
                  tLuid(1).Attributes = %SE_PRIVILEGE_ENABLED
               
                  FUNCTION = AdjustTokenPrivileges( hToken, %FALSE, BYVAL VARPTR(tToken), 4 + (LEN(LUID_AND_ATTRIBUTES) * 2), _
                                                      BYVAL %NULL, BYVAL %NULL )
                   
              Clean_Up:
                  CALL CloseHandle( hToken )
               
              END FUNCTION
              since it is more convenient when setting multiple privileges..

              Cheers

              Florent

              ------------------

              Comment


              • #8
                Microsoft invented LARGE_INTEGER because they didn't have a QUAD type. In most cases,
                it's more useful to use QUAD if you have it, so we replaced LARGE_INTEGER with QUAD
                in the Win32API update of 11 July 2001. This affected a few functions such as
                LookupPrivilegeValue, which apparently had lpLuid defined as LARGE_INTEGER instead of
                as LUID. For consistency, the LUID type will be used with LUIDs in the future.

                Florent, it's not safe to define Priveleges AS BYTE PTR -- that's an actual array,
                not a pointer. TOKEN_PRIVILEGES is one of Microsoft's "fake types", intended as
                documentation rather than to be used in a program. You need to define your own
                version of TOKEN_PRIVILEGES with the appropriate array size, or just allocate a
                generic block of memory and map it in some convenient fashion.

                ------------------
                Tom Hanlin
                PowerBASIC Staff

                Comment


                • #9
                  Tom

                  if you look at the code the byte ptr points to a separate
                  ARRAY of LUID_AND_ATTRIBUTES which is correctly dimensioned.
                  In which way is this unsafe?

                  Cheers

                  Florent

                  ------------------

                  Comment


                  • #10
                    Windows is expecting the actual array element(s), not a pointer to them.
                    Or have I overlooked something?

                    ------------------
                    Tom Hanlin
                    PowerBASIC Staff

                    Comment


                    • #11
                      [UPDATE added later]
                      Hi Tom

                      Oops - I ended up talking about TOKEN_PRIVILEGES whereas
                      the conversation is about LUID_AND_ATTRIBUTES. You are
                      correct in saying that Windows expects an array of
                      LUID_AND_ATTRIBUTES - however it seems windows *casts*
                      the memory to an internal structure which is why it works.

                      This may be a case of better safe than sorry - implementations
                      may change
                      [/UPDATE]

                      Hi Tom

                      Windows is expecting a pointer to TOKEN_PRIVILEGES (it's
                      declared as PTOKEN_PRIVILEGES) according to the MSDN
                      documentation of AdjustTokenPrivileges.

                      Quoting from MSDN:
                      NewState
                      Pointer to a TOKEN_PRIVILEGES structure that specifies
                      an array of privileges and their attributes
                      Declaring Privileges as a pointer or a DWORD would allow us to set it
                      to the required size without us having to edit Win32api.inc. Of course
                      not a big deal either way although adapting our own win32api.inc
                      may mean that some code we post may not be compatible with others^
                      versions...


                      Cheers

                      Florent

                      ------------------


                      [This message has been edited by Florent Heyworth (edited August 13, 2001).]

                      Comment

                      Working...
                      X