• Welcome to Theos PowerBasic Museum 2017.

Unicode and CreateProcessWithLogonW ??

Started by Jim Padgett, September 12, 2011, 04:40:54 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Jim Padgett

PBWin 10 ...
I am attempting to create a process using specific login credentials using CreateProcessWithLogonW  .. with the following questions...


Is WSTRING the same as a unicode string ?  The help file for ucode$ states ' This version of PowerBASIC handles all conversions between ANSI strings and UNICODE strings automatically.

Example

Dim yourname as string, myname as wstring, pcname as wstring ...others omitted

yourname = "jim"
myname = yourname

msgbox str$(len(yourname)) = 3
msgbox str$(len(myname)) = 3
myname = ucode$("jim")
msgbox str$(len(myname)) = 6

I must be missing something??


             myname = UCODE$("jim")
             pcname = UCODE$("game-pc")
             pword = UCODE$("guess")
             expath = UCODE$("C:\windows\system32\notepad.exe")
             cline = UCODE$("")
             cdir = UCODE$("")
             R01 = CreateProcessWithLogonW (STRPTR(myname) , pcname , STRPTR(pword) ,%LOGON_WITH_PROFILE , 0&,  STRPTR(expath) ,0&,&H04000000 ,STRPTR(cdir) ,si , pi)


Should wstring strings be a fixed length string  WSTRINGZ 

I get String Operand Expected error on compile at the first STRPTR(myname) arg ...

winbase.inc shows  ..

DECLARE FUNCTION CreateProcessWithLogonW IMPORT "ADVAPI32.DLL" ALIAS "CreateProcessWithLogonW" ( _
   BYREF lpUsername AS WSTRINGZ _                       ' __in LPCWSTR lpUsername
, BYREF lpDomain AS WSTRINGZ _                         ' __in LPCWSTR lpDomain
, BYREF lpPassword AS WSTRINGZ _                       ' __in LPCWSTR lpPassword
, BYVAL dwLogonFlags AS DWORD _                        ' __in DWORD dwLogonFlags
, BYREF lpApplicationName AS WSTRINGZ _                ' __in LPCWSTR lpApplicationName
, BYREF lpCommandLine AS WSTRINGZ _                    ' __inout LPWSTR lpCommandLine
, BYVAL dwCreationFlags AS DWORD _                     ' __in DWORD dwCreationFlags
, BYVAL lpEnvironment AS DWORD _                       ' __in LPVOID lpEnvironment
, BYREF lpCurrentDirectory AS WSTRINGZ _               ' __in LPCWSTR lpCurrentDirectory
, BYREF lpStartupInfo AS STARTUPINFOW _                ' __in LPSTARTUPINFOW lpStartupInfo
, BYREF lpProcessInformation AS PROCESS_INFORMATION _  ' __out LPPROCESS_INFORMATION lpProcessInformation
) AS LONG                                              ' BOOL



Peter Weis

#1
Hi Jim,
you no longer need to convert it with the compiler PBWIN 10 UCODE$  it converted automatically into WSTRING or WSTRINGZ!

You can write


R01 = CreateProcessWithLogonW ("jim" , "game-pc" ,  pword , %LOGON_WITH_PROFILE , 0&,  "C:\windows\system32notepad.exe" , 0&, &H04000000 , byval 0 ,si , pi)



regards Peter

José Roca

Quote
Is WSTRING the same as a unicode string ?

A WSTRING is a dynamic unicode string, i.e. same as STRING but containing unicode characters instead of ansi characters. A WSTRINGZ is a null-terminated unicode string, i.e. same as ASCIIZ but containing unicode characters instead of ansi characters.

Quote
             myname = UCODE$("jim")
             pcname = UCODE$("game-pc")
             pword = UCODE$("guess")
             expath = UCODE$("C:\windows\system32\notepad.exe")
             cline = UCODE$("")
             cdir = UCODE$("")
             R01 = CreateProcessWithLogonW (STRPTR(myname) , pcname , STRPTR(pword) ,%LOGON_WITH_PROFILE , 0&,  STRPTR(expath) ,0&,&H04000000 ,STRPTR(cdir) ,si , pi)

This is what was used with PB 9 because we lacked native unicode support. As Peter has pointed out, forget the UCODE$/ACODE$ and STRPTRs.

Jim Padgett

WStringZ   are fixed length ?

Is it just me or the older versions of pbasic?  I am wondering how I can use wstring or "jim" or wstringz   all in the same function that uses
wstringz as a declared argument ?

This is what I used to actually make it work (shamelessly borrowed from PB source code forum)...
CreateProcessWithLogonW ( "jim", "game-pc", "guess", %LOGON_WITH_PROFILE, "C:\windows\system32\notepad.exe", _
"" ,%CREATE_DEFAULT_ERROR_MODE Or %CREATE_NEW_CONSOLE Or %CREATE_NEW_PROCESS_GROUP,0& ,"" ,si , pi)

Edited first version:
CreateProcessWithLogonW (myname , pcname , pword ,%LOGON_WITH_PROFILE , 0&, _
expath ,0&,&H04000000 ,cdir ,si , pi)

Other than the declare args being dword pointers to wstringz data and my simply using wstring values ( I'm good with this makes my life easier )
I understand the args up to:
lpEnvironment  I assume a value of 0& is  equal to  an empty string?
lpCurrentDirectory   This time an empty string... instead of 0&  ?

These things make my head hurt ...   :-) 

José Roca

Quote
WStringZ   are fixed length ?

Yes.

Quote
Is it just me or the older versions of pbasic?  I am wondering how I can use wstring or "jim" or wstringz   all in the same function that uses
wstringz as a declared argument ?

If the variable is of type WSTRING and the parameter of type WSTRINGZ, you can pass it by using BYCOPY or BYVAL STRPTR.

Quote
I understand the args up to:
lpEnvironment  I assume a value of 0& is  equal to  an empty string?
lpCurrentDirectory   This time an empty string... instead of 0&  ?

lpEnvironment  is declared as BYVAL DWORD because it is not an string, but an environment block. An environment block consists of a null-terminated block of null-terminated strings.

Patrick de Groot

How do I call this...
Compiler keeps saying Parameter mismatches definition

Function RunAs(Cmd As WString, UserName As WString, Password As WString) As Long
    Local tStartupInfo As STARTUPINFO
    Local tProcessInfo As PROCESS_INFORMATION
    Local r As Long

    tStartupInfo.cb = SizeOf(tStartupInfo)
    tStartupInfo.dwFlags = 0
    tStartupInfo.wShowWindow = %SW_Minimize

    r = CreateProcessWithLogonW(UserName, ".", Password, %LOGON_WITH_PROFILE, "cmd /c", Cmd, _
        %CREATE_DEFAULT_ERROR_MODE Or %CREATE_NEW_CONSOLE Or %CREATE_NEW_PROCESS_GROUP, _
        0, 0, tStartupInfo, tProcessInfo)

    If r Then
        CloseHandle tProcessInfo.hThread
        CloseHandle tProcessInfo.hProcess
    End If
End Function   

Tried string wstring, strptr() (then it says string operand expected)...
Can't I use regular strings with this definition?

Patrick de Groot

hmm if it was defined just using dword i could simply use strptr(string)...? I prefer the string type, at least when calling my own functions
is there an easy/efficient way to convert a string to stringz?

José Roca


Peter Weis

Hello Patrick de Groot,
Just do it so it goes in your case.
Just write it in brackets then convert PowerBASIC properly


FUNCTION RunAs(Cmd AS WSTRING, UserName AS WSTRING, Password AS WSTRING) AS LONG
    LOCAL tStartupInfo AS STARTUPINFO
    LOCAL tProcessInfo AS PROCESS_INFORMATION
    LOCAL r AS LONG

    tStartupInfo.cb = SIZEOF(tStartupInfo)
    tStartupInfo.dwFlags = 0
    tStartupInfo.wShowWindow = %SW_MINIMIZE

    r = CreateProcessWithLogonW((UserName), ".", (Password), %LOGON_WITH_PROFILE, "cmd /c", (Cmd), _
        %CREATE_DEFAULT_ERROR_MODE OR %CREATE_NEW_CONSOLE OR %CREATE_NEW_PROCESS_GROUP, _
        0, BYVAL 0, tStartupInfo, tProcessInfo)

    IF r THEN
        CloseHandle tProcessInfo.hThread
        CloseHandle tProcessInfo.hProcess
    END IF
END FUNCTION
                         

regards Peter

José Roca

It is a shortcut for BYCOPY for those that like to type less. I prefer clarity. Notice that in my declares I always use BYREF even if it is not needed because it's the default. If I did omit it, sometimes I could be in doubt if I really wanted the declare it as BYREF or just forgot to type BYVAL. Similarly, Using BYCOPY is unambiguous, using () can be overlooked. But it's a matter of preference.


Peter Weis

#10
Hello,
I would write down so usually that because it is faster


FUNCTION RunAs(Cmd AS WSTRING, UserName AS WSTRING, Password AS WSTRING) AS LONG
    LOCAL tStartupInfo AS STARTUPINFO
    LOCAL tProcessInfo AS PROCESS_INFORMATION
    LOCAL r AS LONG

    tStartupInfo.cb = SIZEOF(tStartupInfo)
    tStartupInfo.dwFlags = 0
    tStartupInfo.wShowWindow = %SW_MINIMIZE

    r = CreateProcessWithLogonW(BYVAL STRPTR(UserName), ".", BYVAL STRPTR(Password), %LOGON_WITH_PROFILE, "cmd /c", BYVAL STRPTR (Cmd), _
        %CREATE_DEFAULT_ERROR_MODE OR %CREATE_NEW_CONSOLE OR %CREATE_NEW_PROCESS_GROUP, _
        0, BYVAL 0, tStartupInfo, tProcessInfo)

    IF r THEN
        CloseHandle tProcessInfo.hThread
        CloseHandle tProcessInfo.hProcess
    END IF
END FUNCTION                       


But that same write is white it is deadly, and no longer works!


FUNCTION RunAs(Cmd AS STRING, UserName AS STRING, Password AS STRING) AS LONG
    LOCAL tStartupInfo AS STARTUPINFO
    LOCAL tProcessInfo AS PROCESS_INFORMATION
    LOCAL r AS LONG

    tStartupInfo.cb = SIZEOF(tStartupInfo)
    tStartupInfo.dwFlags = 0
    tStartupInfo.wShowWindow = %SW_MINIMIZE

    r = CreateProcessWithLogonW(BYVAL STRPTR(UserName), ".", BYVAL STRPTR(Password), %LOGON_WITH_PROFILE, "cmd /c", BYVAL STRPTR (Cmd), _
        %CREATE_DEFAULT_ERROR_MODE OR %CREATE_NEW_CONSOLE OR %CREATE_NEW_PROCESS_GROUP, _
        0, BYVAL 0, tStartupInfo, tProcessInfo)

    IF r THEN
        CloseHandle tProcessInfo.hThread
        CloseHandle tProcessInfo.hProcess
    END IF
END FUNCTION
                         


I chose the method with clips for Patrick de Groot because it is safe for him. The string is automatically converted to the correct format.

:)

José Roca

> But that same write is white it is deadly, and no longer works!

How is going to work if you're passing a pointer to an ansi string instead of an unicode string? There is not automatic conversion if you use STRPTR.

Peter Weis

#12
Hello Jose,
I've also meant by my example!

With the clamp, it is automatically converted. Strptr is faster because only a pointer is passed!

:)

José Roca

#13
> Strptr is faster because only a pointer is passed!

And what do you think that it is passed when a parameter is declared by reference? Passing a pointer is not faster than passing a pointer :)

Do you know what is faster?


FUNCTION RunAs(Cmd AS WSTRINGZ, UserName AS WSTRINGZ, Password AS WSTRINGZ) AS LONG
...
...


    r = CreateProcessWithLogonW(UserName, ".", Password, %LOGON_WITH_PROFILE, "cmd /c", Cmd, _
        %CREATE_DEFAULT_ERROR_MODE OR %CREATE_NEW_CONSOLE OR %CREATE_NEW_PROCESS_GROUP, _
        0, BYVAL 0, tStartupInfo, tProcessInfo)



Besides, if your concern is speed, why are you using dynamic strings to call a function that requires null terminated strings.

Peter Weis

Hello Jose,
I meant passing BYCOPY is not so fast, because only a new string is generated!