pike.git / src / modules / system / nt.c

version» Context lines:

pike.git/src/modules/system/nt.c:7:   /*    * NT system calls for Pike    *    * Fredrik Hubinette, 1998-08-22    */      #include "global.h"      #include "system_machine.h"   #include "system.h" - #include "port.h" +       #include <errno.h>      #ifdef __NT__   #ifdef HAVE_WINSOCK2_H   #include <winsock2.h>   #else   #include <winsock.h>   #endif - #include <windows.h> +    #include <accctrl.h>   #include <lm.h>   #define SECURITY_WIN32   #define SEC_SUCCESS(Status) ((Status) >= 0)   #ifndef __MINGW32__   #include <sspi.h>   #else   #include <security.h>   #endif    - #include <shlobj.h> - #include <objbase.h> -  +    /* These are defined by winerror.h in recent SDKs. */   #ifndef SEC_E_INSUFFICIENT_MEMORY   #include <issperr.h>   #endif      /*    * Get some wrappers for functions not implemented in old versions    * of WIN32. Needs a Platform SDK installed. The SDK included in    * MSVS 6.0 is not enough.    */
pike.git/src/modules/system/nt.c:58:   #include "program.h"   #include "stralloc.h"   #include "threads.h"   #include "module_support.h"   #include "array.h"   #include "mapping.h"   #include "constants.h"   #include "builtin_functions.h"   #include "interpret.h"   #include "operators.h" - #include "stuff.h" - #include "pike_security.h" +    #include "fdlib.h"      #define sp Pike_sp    - static void throw_nt_error(char *funcname, int err) + static void throw_nt_error(int err)   /*    * Give string equivalents to some of the more common NT error codes.    */   {    char *msg;       switch (err)    {    case ERROR_FILE_NOT_FOUND:    msg = "File not found.";
pike.git/src/modules/system/nt.c:171:       case RPC_S_SERVER_UNAVAILABLE:    msg = "RPC server unavailable.";    break;       case NERR_Success:    msg = "Strange error (NERR_Success).";    break;       default: -  Pike_error("%s: Unknown error 0x%04x (%d)\n", funcname, err, err); +  Pike_error("Unknown error 0x%04x (%d)\n", err, err);    return;    } -  Pike_error("%s: %s\n", funcname, msg); +  Pike_error("%s\n", msg);   }      static void f_cp(INT32 args)   {    char *from, *to;    int ret; -  VALID_FILE_IO("cp","write"); -  get_all_args("cp",args,"%s%s",&from,&to); +  get_all_args(NULL, args, "%s%s", &from, &to);    ret=CopyFile(from, to, 0);    if(!ret) set_errno_from_win32_error (GetLastError());    pop_n_elems(args);    push_int(ret);   }      static void push_tchar(const TCHAR *buf, DWORD len)   {    push_string(make_shared_binary_pcharp(    MKPCHARP(buf,my_log2(sizeof(TCHAR))),len));
pike.git/src/modules/system/nt.c:218:    push_empty_string();    } else {    push_string(make_shared_binary_string(buffer,len-1));    }    break;       case REG_EXPAND_SZ:    type =    ExpandEnvironmentStrings((LPCTSTR)buffer,    buffer+len, -  DO_NOT_WARN((DWORD)(sizeof(buffer)-len-1))); +  (DWORD)(sizeof(buffer)-len-1));    if(type>sizeof(buffer)-len-1 || !type) -  Pike_error("RegGetValue: Failed to expand data.\n"); +  Pike_error("Failed to expand data.\n");    push_text(buffer+len);    break;       case REG_MULTI_SZ:    if (!len) {    push_empty_array();    } else {    push_string(make_shared_binary_string(buffer,len-1));    push_string(make_shared_binary_string("\000",1));    f_divide(2);
pike.git/src/modules/system/nt.c:249:    break;       case REG_DWORD_BIG_ENDIAN:    push_int(EXTRACT_UCHAR(buffer+3)+    (EXTRACT_UCHAR(buffer+2)<<1)+    (EXTRACT_UCHAR(buffer+1)<<2)+    (EXTRACT_UCHAR(buffer)<<3));    break;       default: -  Pike_error("RegGetValue: cannot handle this data type.\n"); +  Pike_error("Cannot handle this data type.\n");    }   }      /* Known hkeys.    *    * This table is used to avoid passing pointers to the pike level. -  * (On W2k/IA64 HKEY is typedefed to struct HKEY__ *). +     *    * NOTE: Order must match the values specified with    * ADD_GLOBAL_INTEGER_CONSTANT() in init_nt_system_calls() below.    */   static const HKEY hkeys[] = {    HKEY_CLASSES_ROOT,    HKEY_LOCAL_MACHINE,    HKEY_CURRENT_USER,    HKEY_USERS,    /* HKEY_CURRENT_CONFIG */
pike.git/src/modules/system/nt.c:309:    *!    *! @param index    *! Value name.    *!    *! @returns    *! Returns the value stored at the specified location in the register    *! if any. Returns @expr{UNDEFINED@} on missing keys, throws errors    *! on other failures.    *!    *! @note -  *! This function threw errors on missing keys in Pike 7.6 and earlier -  *! (see @[System.RegGetValue_76()]). -  *! -  *! @note +     *! This function is only available on Win32 systems.    *!    *! @seealso -  *! @[RegGetValues()], @[RegGetKeyNames()], @[System.RegGetValue_76()] +  *! @[RegGetValues()], @[RegGetKeyNames()]    */   void f_RegGetValue(INT32 args)   {    long ret;    INT_TYPE hkey_num;    HKEY new_key;    char *key, *ind;    DWORD len,type;    char buffer[8192];    len=sizeof(buffer)-1; -  get_all_args("RegGetValue", args, "%i%s%s", -  &hkey_num, &key, &ind); +  get_all_args(NULL, args, "%i%s%s", &hkey_num, &key, &ind);       if ((hkey_num < 0) || ((unsigned int)hkey_num >= NELEM(hkeys))) { -  Pike_error("Unknown hkey: %d\n", hkey_num); +  Pike_error("Unknown hkey: %d.\n", hkey_num);    }       ret = RegOpenKeyEx(hkeys[hkey_num], (LPCTSTR)key, 0, KEY_READ, &new_key);    if ((ret == ERROR_FILE_NOT_FOUND) ||    (ret == ERROR_PATH_NOT_FOUND)) {    pop_n_elems(args);    push_undefined();    return;    }    if(ret != ERROR_SUCCESS) -  throw_nt_error("RegOpenKeyEx", ret); +  throw_nt_error(ret);       ret=RegQueryValueEx(new_key,ind, 0, &type, buffer, &len);    RegCloseKey(new_key);       if(ret==ERROR_SUCCESS)    {    pop_n_elems(args);    push_regvalue(type, buffer, len);    } else if (ret == ERROR_FILE_NOT_FOUND) {    pop_n_elems(args);    push_undefined();    }else{ -  throw_nt_error("RegQueryValueEx", ret); +  throw_nt_error(ret);    }   }      static void do_regclosekey(HKEY key)   {    RegCloseKey(key);   }      /*! @decl array(string) RegGetKeyNames(int hkey, string key)    *!
pike.git/src/modules/system/nt.c:395:    *! @example    *! > RegGetKeyNames(HKEY_CURRENT_USER, "Keyboard Layout");    *! (1) Result: ({    *! "IMEtoggle",    *! "Preload",    *! "Substitutes",    *! "Toggle"    *! })    *!    *! @note -  *! This function threw errors on missing @[key] in Pike 7.6 and earlier -  *! (see @[System.RegGetKeyNames_76()]). -  *! -  *! @note +     *! This function is only available on Win32 systems.    *!    *! @seealso -  *! @[RegGetValue()], @[RegGetValues()], @[System.RegGetKeyNames_76()] +  *! @[RegGetValue()], @[RegGetValues()]    */   void f_RegGetKeyNames(INT32 args)   {    INT_TYPE hkey_num;    char *key;    int i,ret;    HKEY new_key;    ONERROR tmp; -  get_all_args("RegGetKeyNames", args, "%i%s", -  &hkey_num, &key); +  get_all_args(NULL, args, "%i%s", &hkey_num, &key);       if ((hkey_num < 0) || ((unsigned int)hkey_num >= NELEM(hkeys))) { -  Pike_error("Unknown hkey: %d\n", hkey_num); +  Pike_error("Unknown hkey: %d.\n", hkey_num);    }       ret = RegOpenKeyEx(hkeys[hkey_num], (LPCTSTR)key, 0, KEY_READ, &new_key);    if ((ret == ERROR_FILE_NOT_FOUND) ||    (ret == ERROR_PATH_NOT_FOUND)) {    pop_n_elems(args);    push_undefined();    return;    }    if(ret != ERROR_SUCCESS) -  throw_nt_error("RegGetKeyNames[RegOpenKeyEx]", ret); +  throw_nt_error(ret);       SET_ONERROR(tmp, do_regclosekey, new_key);       pop_n_elems(args);       for(i=0;;i++)    {    TCHAR buf[1024];    DWORD len=sizeof(buf)-1;    FILETIME tmp2;
pike.git/src/modules/system/nt.c:451:    {    case ERROR_SUCCESS:    check_stack(1);    push_tchar(buf,len);    continue;       case ERROR_NO_MORE_ITEMS:    break;       default: -  throw_nt_error("RegGetKeyNames[RegEnumKeyEx]", ret); +  throw_nt_error(ret);    }    break;    }    CALL_AND_UNSET_ONERROR(tmp);    f_aggregate(i);   }      /*! @decl mapping(string:string|int|array(string)) RegGetValues(int hkey, @    *! string key)    *!
pike.git/src/modules/system/nt.c:489:    *! Returns @expr{UNDEFINED@} on missing @[key].    *! Throws errors on other failures.    *!    *! @example    *! > RegGetValues(HKEY_CURRENT_USER, "Keyboard Layout\\Preload");    *!(5) Result: ([    *! "1":"0000041d"    *! ])    *!    *! @note -  *! This function threw errors on missing @[key] in Pike 7.6 and earlier -  *! (see @[System.RegGetValues_76()]). -  *! -  *! @note +     *! This function is only available on Win32 systems.    *!    *! @seealso -  *! @[RegGetValue()], @[RegGetKeyNames()], @[System.RegGetValues_76()] +  *! @[RegGetValue()], @[RegGetKeyNames()]    */   void f_RegGetValues(INT32 args)   {    INT_TYPE hkey_num;    char *key;    int i,ret;    HKEY new_key;    ONERROR tmp;    -  get_all_args("RegGetValues", args, "%i%s", -  &hkey_num, &key); +  get_all_args(NULL, args, "%i%s", &hkey_num, &key);       if ((hkey_num < 0) || ((unsigned int)hkey_num >= NELEM(hkeys))) { -  Pike_error("Unknown hkey: %d\n", hkey_num); +  Pike_error("Unknown hkey: %d.\n", hkey_num);    }       ret = RegOpenKeyEx(hkeys[hkey_num], (LPCTSTR)key, 0, KEY_READ, &new_key);       if ((ret == ERROR_FILE_NOT_FOUND) ||    (ret == ERROR_PATH_NOT_FOUND)) {    pop_n_elems(args);    push_undefined();    return;    }    if(ret != ERROR_SUCCESS) -  throw_nt_error("RegOpenKeyEx", ret); +  throw_nt_error(ret);       SET_ONERROR(tmp, do_regclosekey, new_key);    pop_n_elems(args);       for(i=0;;i++)    {    TCHAR buf[1024];    char buffer[8192];    DWORD len=sizeof(buf)-1;    DWORD buflen=sizeof(buffer)-1;
pike.git/src/modules/system/nt.c:551:    check_stack(2);    push_tchar(buf,len);    push_regvalue(type,buffer,buflen);    continue;       case ERROR_NO_MORE_ITEMS:    break;       default:    RegCloseKey(new_key); -  throw_nt_error("RegGetValues[RegEnumKeyEx]", ret); +  throw_nt_error(ret);    }    break;    }    CALL_AND_UNSET_ONERROR(tmp);    f_aggregate_mapping(i*2);   }      /*! @module System    */    - /*! @decl string|int|array(string) RegGetValue_76(int hkey, string key, @ -  *! string index) -  *! -  *! Get a single value from the register (COMPAT). -  *! -  *! Pike 7.6 compatibility implementation of @[RegGetValue()]. -  *! The difference being that this function throws errors when -  *! keys are missing. -  *! -  *! @note -  *! This function is only available on Win32 systems. -  *! -  *! @seealso -  *! @[RegGetKeyNames_76()], @[RegGetValues_76()], @[RegGetValue()] -  */ - void f_RegGetValue_76(INT32 args) - { -  if (args) { -  assign_svalues_no_free(Pike_sp, Pike_sp-args, args, BIT_MIXED); -  Pike_sp += args; -  } -  f_RegGetValue(args); -  if (IS_UNDEFINED(Pike_sp-1)) { -  /* FIXME: We don't actually know which of the two calls that failed, -  * but the caller probably doesn't care. */ -  throw_nt_error("RegQueryValueEx", ERROR_FILE_NOT_FOUND); -  } -  stack_pop_n_elems_keep_top(args); - } -  - /*! @decl array(string) RegGetKeyNames_76(int hkey, string key) -  *! -  *! Get a list of value key names from the register (COMPAT). -  *! -  *! Pike 7.6 compatibility implementation of @[RegGetKeyNames()]. -  *! The difference being that this function throws errors when -  *! keys are missing. -  *! -  *! @note -  *! This function is only available on Win32 systems. -  *! -  *! @seealso -  *! @[RegGetValue()], @[RegGetValues_76()], @[RegGetKeyNames()] -  */ - void f_RegGetKeyNames_76(INT32 args) - { -  if (args) { -  assign_svalues_no_free(Pike_sp, Pike_sp-args, args, BIT_MIXED); -  Pike_sp += args; -  } -  f_RegGetKeyNames(args); -  if (IS_UNDEFINED(Pike_sp-1)) { -  throw_nt_error("RegGetKeyNames[RegOpenKeyEx]", ERROR_FILE_NOT_FOUND); -  } -  stack_pop_n_elems_keep_top(args); - } -  - /*! @decl mapping(string:string|int|array(string)) RegGetValues_76(int hkey, @ -  *! string key) -  *! -  *! Get multiple values from the register (COMPAT). -  *! -  *! Pike 7.6 compatibility implementation of @[RegGetValues()]. -  *! The difference being that this function throws errors when -  *! keys are missing. -  *! -  *! @note -  *! This function is only available on Win32 systems. -  *! -  *! @seealso -  *! @[RegGetValue_76()], @[RegGetKeyNames_76()], @[RegGetValues()] -  */ - void f_RegGetValues_76(INT32 args) - { -  if (args) { -  assign_svalues_no_free(Pike_sp, Pike_sp-args, args, BIT_MIXED); -  Pike_sp += args; -  } -  f_RegGetValues(args); -  if (IS_UNDEFINED(Pike_sp-1)) { -  throw_nt_error("RegOpenKeyEx", ERROR_FILE_NOT_FOUND); -  } -  stack_pop_n_elems_keep_top(args); - } -  -  +    /*! @decl int FreeConsole()    *!    *! Detaches the calling process from its console.    *!    *! @note    *! Before calling this function, @[Stdio.stderr], @[Stdio.stdout] and    *! @[Stdio.stdin] must be closed.    *!    *! @note    *! Only available on certain Windows systems.
pike.git/src/modules/system/nt.c:712:    *! Only available on certain Windows systems.    *!    *! @returns    *! 0 on success, non-zero otherwise.    */   #ifdef HAVE_ATTACHCONSOLE   void f_attachconsole(INT32 args)   {    int rv;    int pid; -  get_all_args("AttachConsole", args, "%d", -  &pid); +  get_all_args(NULL, args, "%d", &pid);       rv = (int)AttachConsole(pid);       push_int(rv);   }   #endif /* HAVE_ATTACHCONSOLE */         static struct program *token_program;    - #define THIS_TOKEN (*(HANDLE *)(Pike_fp->current_storage)) + #define THIS_TOKEN (*(HANDLE *)CURRENT_STORAGE)      typedef BOOL (WINAPI *logonusertype)(LPSTR,LPSTR,LPSTR,DWORD,DWORD,PHANDLE);   typedef DWORD (WINAPI *getlengthsidtype)(PSID);      static logonusertype logonuser;   static getlengthsidtype getlengthsid;      #define LINKFUNC(RET,NAME,TYPE) \    typedef RET (WINAPI * PIKE_CONCAT(NAME,type)) TYPE ; \    static PIKE_CONCAT(NAME,type) NAME
pike.git/src/modules/system/nt.c:753:   LINKFUNC(DWORD,getnamedsecurityinfo,    (LPTSTR,SE_OBJECT_TYPE,SECURITY_INFORMATION,PSID*,PSID*,PACL*,PACL*,PSECURITY_DESCRIPTOR*) );      LINKFUNC(BOOL,initializeacl, (PACL,DWORD,DWORD) );   LINKFUNC(BOOL,addaccessallowedace, (PACL,DWORD,DWORD,PSID) );   LINKFUNC(BOOL,addaccessdeniedace, (PACL,DWORD,DWORD,PSID) );   LINKFUNC(BOOL,addauditaccessace, (PACL,DWORD,DWORD,PSID,BOOL,BOOL) );      HINSTANCE advapilib;    - #define THIS_PSID (*(PSID *)Pike_fp->current_storage) + #define THIS_PSID (*(PSID *)CURRENT_STORAGE)   static struct program *sid_program;   static void init_sid(struct object *o)   {    THIS_PSID=0;   }      static void exit_sid(struct object *o)   {    if(THIS_PSID)    { -  free((char *)THIS_PSID); +  free(THIS_PSID);    THIS_PSID=0;    }   }      static void f_sid_eq(INT32 args)   { -  check_all_args("system.SID->`==",args,BIT_MIXED,0); -  if(TYPEOF(sp[-1]) == T_OBJECT) +  if(args && TYPEOF(sp[-1]) == T_OBJECT)    {    PSID *tmp=(PSID *)get_storage(sp[-1].u.object,sid_program);    if(tmp)    {    if( (!THIS_PSID && !*tmp) ||    (THIS_PSID && *tmp && equalsid(THIS_PSID, *tmp) ))    {    pop_stack();    push_int(1);    return;
pike.git/src/modules/system/nt.c:798:   }      static void f_sid_account(INT32 args)   {    char foo[1];    DWORD namelen=0;    DWORD domainlen=0;    char *sys=0;    SID_NAME_USE type;    -  check_all_args("SID->account",args,BIT_STRING|BIT_VOID, 0); +  check_all_args(NULL, args, BIT_STRING|BIT_VOID, 0);    if(args) sys=sp[-1].u.string->str;       if(!THIS_PSID) Pike_error("SID->account on uninitialized SID.\n");    lookupaccountsid(sys,    THIS_PSID,    foo,    &namelen,    foo,    &domainlen,    &type);
pike.git/src/modules/system/nt.c:830:    STR0(dom),    &domainlen,    &type))    {    push_string(end_shared_string(name));    push_string(end_shared_string(dom));    push_int(type);    f_aggregate(3);    return;    } -  free((char *)dom); -  free((char *)name); +  free(dom); +  free(name);    }    errno=GetLastError();    pop_n_elems(args);    push_array(allocate_array(3));      }      /*! @decl object LogonUser(string username, string|int(0..0) domain, @    *! string password, int|void logon_type, @    *! int|void logon_provider)
pike.git/src/modules/system/nt.c:885:    *! @note    *! This function is only available on some Win32 systems.    */   void f_LogonUser(INT32 args)   {    LPTSTR username, domain, pw;    DWORD logontype, logonprovider;    HANDLE x;    BOOL ret;    -  ASSERT_SECURITY_ROOT("System.LogonUser"); -  -  check_all_args("System.LogonUser",args, +  check_all_args(NULL, args,    BIT_STRING, BIT_INT | BIT_STRING, BIT_STRING,    BIT_INT | BIT_VOID, BIT_INT | BIT_VOID,0);       username=(LPTSTR)sp[-args].u.string->str;       if(TYPEOF(sp[1-args]) == T_STRING)    domain=(LPTSTR)sp[1-args].u.string->str;    else    domain=0;   
pike.git/src/modules/system/nt.c:916:    case 4: logontype=sp[3-args].u.integer;    case 3:    case 2:    case 1:    case 0: break;    }       THREADS_ALLOW();    ret=logonuser(username, domain, pw, logontype, logonprovider, &x);    THREADS_DISALLOW(); +  pop_n_elems(args);    if(ret)    {    struct object *o; -  pop_n_elems(args); -  o=low_clone(token_program); +  o=fast_clone_object(token_program);    (*(HANDLE *)(o->storage))=x;    push_object(o);    }else{    errno=GetLastError(); -  pop_n_elems(args); +     push_int(0);    }   }      static void init_token(struct object *o)   { -  THIS_TOKEN = DO_NOT_WARN(INVALID_HANDLE_VALUE); +  THIS_TOKEN = INVALID_HANDLE_VALUE;   }      static void exit_token(struct object *o)   {    CloseHandle(THIS_TOKEN); -  THIS_TOKEN = DO_NOT_WARN(INVALID_HANDLE_VALUE); +  THIS_TOKEN = INVALID_HANDLE_VALUE;   }      static void low_encode_user_info_0(USER_INFO_0 *tmp)   {   #define SAFE_PUSH_WSTR(X) \    if(X) \    push_string(make_shared_string1((p_wchar1 *) X)); \    else \    push_int(0)   
pike.git/src/modules/system/nt.c:1186:    {    case 0: low_encode_localgroup_users_info_0 ((LOCALGROUP_USERS_INFO_0 *) u);break;    default:    Pike_error("Unsupported LOCALGROUPUSERSINFO level.\n");    }   }      static void low_encode_localgroup_members_info_0(LOCALGROUP_MEMBERS_INFO_0 *tmp)   {    - #define SAFE_PUSH_SID(X) do { \ -  if(getlengthsid && (X) && sid_program) { \ -  int lentmp=getlengthsid( (X) ); \ -  PSID psidtmp=(PSID)xalloc(lentmp); \ -  struct object *o=low_clone(sid_program); \ -  MEMCPY( psidtmp, (X), lentmp); \ -  (*(PSID *)(o->storage))=psidtmp; \ -  push_object(o); \ -  } else { \ -  push_int(0); \ + #define SAFE_PUSH_SID(X) do { \ +  if(getlengthsid && (X) && sid_program) { \ +  int lentmp=getlengthsid( (X) ); \ +  PSID psidtmp=xalloc(lentmp); \ +  struct object *o=fast_clone_object(sid_program); \ +  memcpy( psidtmp, (X), lentmp); \ +  (*(PSID *)(o->storage))=psidtmp; \ +  push_object(o); \ +  } else { \ +  push_int(0); \    } } while(0)       SAFE_PUSH_SID(tmp->lgrmi0_sid);   }      static void low_encode_localgroup_members_info_1(LOCALGROUP_MEMBERS_INFO_1 *tmp)   {    low_encode_localgroup_members_info_0((LOCALGROUP_MEMBERS_INFO_0 *)tmp);    push_int(tmp->lgrmi1_sidusage);    SAFE_PUSH_WSTR(tmp->lgrmi1_name);
pike.git/src/modules/system/nt.c:1376:    *! @[NetGetAnyDCName()]    */   void f_NetUserGetInfo(INT32 args)   {    char *to_free1=NULL,*to_free2=NULL;    BYTE *tmp=0;    DWORD level;    LPWSTR server, user;    NET_API_STATUS ret;    -  check_all_args("NetUserGetInfo",args,BIT_STRING|BIT_INT, BIT_STRING, BIT_VOID | BIT_INT, 0); +  check_all_args(NULL,args,BIT_STRING|BIT_INT, BIT_STRING, BIT_VOID | BIT_INT, 0);       if(args>2)    level=sp[2-args].u.integer;    else    level=1;       switch(level)    {    case 0: case 1: case 2: case 3: case 10: case 11: case 20:    break;    default:    Pike_error("Unsupported information level in NetUserGetInfo.\n");    }       if(TYPEOF(sp[-args]) == T_STRING)    {    server=(LPWSTR)require_wstring1(sp[-args].u.string,&to_free1);    if(!server) -  Pike_error("NetUserGetInfo, server name string is too wide.\n"); +  Pike_error("Server name string is too wide.\n");    }else{    server=NULL;    }       user=(LPWSTR)require_wstring1(sp[1-args].u.string,&to_free2);    if(!user)    {    if(to_free1) free(to_free1); -  Pike_error("NetUserGetInfo, user name string is too wide.\n"); +  Pike_error("User name string is too wide.\n");    }       THREADS_ALLOW();    ret=netusergetinfo(server,user,level,&tmp);    THREADS_DISALLOW();       pop_n_elems(args);    if(to_free1) free(to_free1);    if(to_free2) free(to_free2);       if (ret == NERR_Success)    {    encode_user_info(tmp,level);    netapibufferfree(tmp);    }    else -  throw_nt_error("NetGetUserInfo", ret); +  throw_nt_error(ret);   }      /*! @decl array(string|array(string|int)) @    *! NetUserEnum(string|int(0..0)|void server, @    *! int|void level, int|void filter)    *!    *! Get information about network users.    *!    *! @param server    *! Server the users exist on.
pike.git/src/modules/system/nt.c:1472:   {    char *to_free1=NULL;    DWORD level=0;    DWORD filter=0;    LPWSTR server=NULL;    INT32 pos=0;    struct array *a=0;    DWORD resume=0;    NET_API_STATUS ret;    -  /* fprintf(stderr,"before: sp=%p args=%d (base=%p)\n",sp,args,sp-args); */ +  check_all_args(NULL,args,BIT_STRING|BIT_INT|BIT_VOID, BIT_INT|BIT_VOID,BIT_INT|BIT_VOID,0);    -  check_all_args("NetUserEnum",args,BIT_STRING|BIT_INT|BIT_VOID, BIT_INT|BIT_VOID,BIT_INT|BIT_VOID,0); -  +     switch(args)    {    default:filter=sp[2-args].u.integer;    case 2: level=sp[1-args].u.integer;    switch(level)    {    case 0: case 1: case 2: case 3: case 10: case 11: case 20:    break;    default: -  Pike_error("Unsupported information level in NetUserEnum.\n"); +  Pike_error("Unsupported information level.\n");    }       case 1:    if(TYPEOF(sp[-args]) == T_STRING)    server=(LPWSTR)require_wstring1(sp[-args].u.string,&to_free1);       case 0: break;    }       pop_n_elems(args);    -  /* fprintf(stderr,"now: sp=%p\n",sp); */ -  +     ret = ERROR_MORE_DATA;       do    {    DWORD read=0, total=0, e;    LPBYTE buf=0,ptr;       THREADS_ALLOW();    ret=netuserenum(server,    level,
pike.git/src/modules/system/nt.c:1536:    sp--;    dmalloc_touch_svalue(sp);    pos++;    if(pos>=a->size) break;    ptr+=sizeof_user_info(level);    }    netapibufferfree(buf);    }    else    { if (to_free1) free(to_free1); -  throw_nt_error("NetUserEnum", ret); +  throw_nt_error(ret);    return;    }    } while (ret == ERROR_MORE_DATA);       if (to_free1) free(to_free1);   }         /*! @decl array(string|array(string|int)) @    *! NetGroupEnum(string|int(0..0)|void server, int|void level)
pike.git/src/modules/system/nt.c:1587:   void f_NetGroupEnum(INT32 args)   {    char *to_free1=NULL, *tmp_server=NULL;    DWORD level=0;    LPWSTR server=NULL;    INT32 pos=0;    struct array *a=0;    DWORD resume=0;    NET_API_STATUS ret;    -  check_all_args("NetGroupEnum",args,BIT_STRING|BIT_INT|BIT_VOID, BIT_INT|BIT_VOID,0); +  check_all_args(NULL,args,BIT_STRING|BIT_INT|BIT_VOID, BIT_INT|BIT_VOID,0);       if(args && TYPEOF(sp[-args]) == T_STRING)    server=(LPWSTR)require_wstring1(sp[-args].u.string,&to_free1);       if(args>1 && TYPEOF(sp[1-args]) == T_INT) {    level = sp[1-args].u.integer;    switch(level)    {    case 0: case 1: case 2:    break;    default: -  Pike_error("Unsupported information level in NetGroupEnum.\n"); +  Pike_error("Unsupported information level.\n");    }    }       pop_n_elems(args);       do    {    DWORD read=0, total=0, e;    LPBYTE buf=0,ptr;   
pike.git/src/modules/system/nt.c:1640:    dmalloc_touch_svalue(sp);    pos++;    if(pos>=a->size) break;    ptr+=sizeof_group_info(level);    }    netapibufferfree(buf);    }    else    {    if (to_free1) free(to_free1); -  throw_nt_error("NetGroupEnum", ret); +  throw_nt_error(ret);    return;    }    } while (ret == ERROR_MORE_DATA);       if(to_free1) free(to_free1);   }      /*! @decl array(array(string|int)) @    *! NetLocalGroupEnum(string|int(0..0)|void server, int|void level)    *!
pike.git/src/modules/system/nt.c:1689:   void f_NetLocalGroupEnum(INT32 args)   {    char *to_free1=NULL, *tmp_server=NULL;    DWORD level=0;    LPWSTR server=NULL;    INT32 pos=0;    struct array *a=0;    DWORD resume=0;    NET_API_STATUS ret;    -  check_all_args("NetLocalGroupEnum",args,BIT_STRING|BIT_INT|BIT_VOID, BIT_INT|BIT_VOID,0); +  check_all_args(NULL,args,BIT_STRING|BIT_INT|BIT_VOID, BIT_INT|BIT_VOID,0);       if(args && TYPEOF(sp[-args]) == T_STRING)    server=(LPWSTR)require_wstring1(sp[-args].u.string,&to_free1);       if(args>1 && TYPEOF(sp[1-args]) == T_INT) {    level = sp[1-args].u.integer;    switch(level)    {    case 0: case 1:    break;    default: -  Pike_error("Unsupported information level in NetLocalGroupEnum.\n"); +  Pike_error("Unsupported information level.\n");    }    }       pop_n_elems(args);       do    {    DWORD read=0, total=0, e;    LPBYTE buf=0,ptr;   
pike.git/src/modules/system/nt.c:1742:    dmalloc_touch_svalue(sp);    pos++;    if(pos>=a->size) break;    ptr+=sizeof_localgroup_info(level);    }    netapibufferfree(buf);    }    else    {    if (to_free1) free(to_free1); -  throw_nt_error("NetLocalGroupEnum", ret); +  throw_nt_error(ret);    }    } while (ret == ERROR_MORE_DATA);       if(to_free1) free(to_free1);   }      /*! @decl array(array(string|int)) @    *! NetUserGetGroups(string|int(0..0) server, string user, int|void level)    *!    *! Get information about group membership for a network user.
pike.git/src/modules/system/nt.c:1795:    char *to_free1=NULL, *to_free2=NULL, *tmp_server=NULL;    DWORD level=0;    LPWSTR server=NULL;    LPWSTR user=NULL;    INT32 pos=0;    struct array *a=0;    DWORD read=0, total=0, e;    NET_API_STATUS ret;    LPBYTE buf=0,ptr;    -  check_all_args("NetUserGetGroups",args,BIT_STRING|BIT_INT, BIT_STRING,BIT_INT|BIT_VOID, 0); +  check_all_args(NULL,args,BIT_STRING|BIT_INT, BIT_STRING,BIT_INT|BIT_VOID, 0);       if(args>0 && TYPEOF(sp[-args]) == T_STRING)    server=(LPWSTR)require_wstring1(sp[-args].u.string,&to_free1);       if(args>1 && TYPEOF(sp[-args+1]) == T_STRING)    user=(LPWSTR)require_wstring1(sp[-args+1].u.string,&to_free2);       if(args>2 && TYPEOF(sp[2-args]) == T_INT) {    level = sp[2-args].u.integer;    switch(level)    {    case 0: case 1:    break;    default: -  Pike_error("Unsupported information level in NetUserGetGroups.\n"); +  Pike_error("Unsupported information level.\n");    }    }       pop_n_elems(args);          THREADS_ALLOW();    ret=netusergetgroups(server,    user,    level,
pike.git/src/modules/system/nt.c:1850:    ptr+=sizeof_group_users_info(level);    }    netapibufferfree(buf);    if(to_free1) free(to_free1);    if(to_free2) free(to_free2);    }    else    {    if(to_free1) free(to_free1);    if(to_free2) free(to_free2); -  throw_nt_error("NetUserGetGroups", ret); +  throw_nt_error(ret);    }   }      /*! @decl array(string) @    *! NetUserGetLocalGroups(string|int(0..0) server, @    *! string user, int|void level, int|void flags)    *!    *! Get information about group membership for a local network user.    *!    *! @param server
pike.git/src/modules/system/nt.c:1907:    DWORD level=0;    DWORD flags=0;    LPWSTR server=NULL;    LPWSTR user=NULL;    INT32 pos=0;    struct array *a=0;    DWORD read=0, total=0, e;    NET_API_STATUS ret;    LPBYTE buf=0,ptr;    -  check_all_args("NetUserGetLocalGroups",args,BIT_STRING|BIT_INT, BIT_STRING,BIT_INT|BIT_VOID, BIT_INT|BIT_VOID, 0); +  check_all_args(NULL,args,BIT_STRING|BIT_INT, BIT_STRING,BIT_INT|BIT_VOID, BIT_INT|BIT_VOID, 0);       if(args>0 && TYPEOF(sp[-args]) == T_STRING)    server=(LPWSTR)require_wstring1(sp[-args].u.string,&to_free1);       if(args>1 && TYPEOF(sp[-args+1]) == T_STRING)    user=(LPWSTR)require_wstring1(sp[-args+1].u.string,&to_free2);       if(args>2 && TYPEOF(sp[2-args]) == T_INT) {    level = sp[2-args].u.integer;    switch(level)    {    case 0:    break;    default: -  Pike_error("Unsupported information level in NetUserGetLocalGroups.\n"); +  Pike_error("Unsupported information level.\n");    }    }       if(args>3 && TYPEOF(sp[3-args]) == T_INT)    flags = sp[3-args].u.integer;       pop_n_elems(args);          THREADS_ALLOW();
pike.git/src/modules/system/nt.c:1965:    pos++;    if(pos>=a->size) break;    ptr+=sizeof_localgroup_users_info(level);    }    netapibufferfree(buf);    break;       default:    if(to_free1) free(to_free1);    if(to_free2) free(to_free2); -  throw_nt_error("NetUserGetLocalGroups", ret); +  throw_nt_error(ret);    }    if(to_free1) free(to_free1);    if(to_free2) free(to_free2);   }      /*! @decl array(string|array(int|string)) @    *! NetGroupGetUsers(string|int(0..0) server, @    *! string group, int|void level)    *!    *! Get information about group membership for a network group.
pike.git/src/modules/system/nt.c:2016:   void f_NetGroupGetUsers(INT32 args)   {    char *to_free1=NULL, *to_free2=NULL, *tmp_server=NULL;    DWORD level=0;    LPWSTR server=NULL;    LPWSTR group=NULL;    INT32 pos=0;    struct array *a=0;    DWORD resume=0;    -  check_all_args("NetGroupGetUsers",args,BIT_STRING|BIT_INT|BIT_VOID, BIT_STRING, BIT_INT|BIT_VOID,0); +  check_all_args(NULL,args,BIT_STRING|BIT_INT|BIT_VOID, BIT_STRING, BIT_INT|BIT_VOID,0);       if(args && TYPEOF(sp[-args]) == T_STRING)    server=(LPWSTR)require_wstring1(sp[-args].u.string,&to_free1);       if(args>1 && TYPEOF(sp[1-args]) == T_STRING)    group=(LPWSTR)require_wstring1(sp[1-args].u.string,&to_free2);       if(args>2 && TYPEOF(sp[2-args]) == T_INT) {    level = sp[2-args].u.integer;    switch(level)    {    case 0: case 1:    break;    default: -  Pike_error("Unsupported information level in NetGroupGetUsers.\n"); +  Pike_error("Unsupported information level.\n");    }    }       pop_n_elems(args);       while(1)    {    DWORD read=0, total=0, e;    NET_API_STATUS ret;    LPBYTE buf=0,ptr;
pike.git/src/modules/system/nt.c:2078:    if(pos>=a->size) break;    ptr+=sizeof_group_users_info(level);    }    netapibufferfree(buf);    if(ret==ERROR_MORE_DATA) continue;    break;       default:    if(to_free1) free(to_free1);    if(to_free2) free(to_free2); -  throw_nt_error("NetGroupGetUsers", ret); +  throw_nt_error(ret);    }    break;    }    if(to_free1) free(to_free1);    if(to_free2) free(to_free2);   }      /*! @decl array(string|array(int|string)) @    *! NetLocalGroupGetMembers(string|int(0..0) server, @    *! string group, int|void level)
pike.git/src/modules/system/nt.c:2133:   void f_NetLocalGroupGetMembers(INT32 args)   {    char *to_free1=NULL, *to_free2=NULL, *tmp_server=NULL;    DWORD level=0;    LPWSTR server=NULL;    LPWSTR group=NULL;    INT32 pos=0;    struct array *a=0;    DWORD resume=0;    -  check_all_args("NetLocalGroupGetMembers",args,BIT_STRING|BIT_INT|BIT_VOID, BIT_STRING, BIT_INT|BIT_VOID,0); +  check_all_args(NULL,args,BIT_STRING|BIT_INT|BIT_VOID, BIT_STRING, BIT_INT|BIT_VOID,0);       if(args && TYPEOF(sp[-args]) == T_STRING)    server=(LPWSTR)require_wstring1(sp[-args].u.string,&to_free1);       if(args>1 && TYPEOF(sp[1-args]) == T_STRING)    group=(LPWSTR)require_wstring1(sp[1-args].u.string,&to_free2);       if(args>2 && TYPEOF(sp[2-args]) == T_INT) {    level = sp[2-args].u.integer;    switch(level)    {    case 0: case 1: case 2: case 3:    break;    default: -  Pike_error("Unsupported information level in NetLocalGroupGetMembers.\n"); +  Pike_error("Unsupported information level.\n");    }    }       pop_n_elems(args);       while(1)    {    DWORD read=0, total=0, e;    NET_API_STATUS ret;    LPBYTE buf=0,ptr;
pike.git/src/modules/system/nt.c:2178:    &resume);    THREADS_DISALLOW();    if(!a)    push_array(a=allocate_array(total));       switch(ret)    {    case ERROR_NO_SUCH_ALIAS:    if(to_free1) free(to_free1);    if(to_free2) free(to_free2); -  Pike_error("NetLocalGroupGetMembers: No such alias.\n"); +  Pike_error("No such alias.\n");    break;       case NERR_Success:    case ERROR_MORE_DATA:    ptr=buf;    for(e=0;e<read;e++)    {    encode_localgroup_members_info(ptr,level);    a->item[pos]=sp[-1];    sp--;
pike.git/src/modules/system/nt.c:2201:    if(pos>=a->size) break;    ptr+=sizeof_localgroup_members_info(level);    }    netapibufferfree(buf);    if(ret==ERROR_MORE_DATA) continue;    break;       default:    if(to_free1) free(to_free1);    if(to_free2) free(to_free2); -  throw_nt_error("NetLocalGroupGetMembers", ret); +  throw_nt_error(ret);    break;    }    break;    }    if(to_free1) free(to_free1);    if(to_free2) free(to_free2);   }      /*! @decl string NetGetDCName(string|int(0..0) server, string domain)    *!
pike.git/src/modules/system/nt.c:2241:    *! @[NetGroupGetUsers()], @[NetLocalGroupGetMembers()],    *! @[NetGetAnyDCName()]    */   void f_NetGetDCName(INT32 args)   {    char *to_free1=NULL,*to_free2=NULL;    BYTE *tmp=0;    LPWSTR server, domain;    NET_API_STATUS ret;    -  check_all_args("NetGetDCName",args,BIT_STRING|BIT_INT, BIT_STRING, 0); +  check_all_args(NULL,args,BIT_STRING|BIT_INT, BIT_STRING, 0);       if(TYPEOF(sp[-args]) == T_STRING)    {    server=(LPWSTR)require_wstring1(sp[-args].u.string,&to_free1);    if(!server) -  Pike_error("NetGetDCName, server name string is too wide.\n"); +  Pike_error("Server name string is too wide.\n");    }else{    server=NULL;    }       domain=(LPWSTR)require_wstring1(sp[1-args].u.string,&to_free2);    if(!domain)    {    if(to_free1) free(to_free1); -  Pike_error("NetGetDCName, domain name string is too wide.\n"); +  Pike_error("Domain name string is too wide.\n");    }       THREADS_ALLOW();    ret=netgetdcname(server,domain,&tmp);    THREADS_DISALLOW();       pop_n_elems(args);    if(to_free1) free(to_free1);    if(to_free2) free(to_free2);       switch(ret)    {    case NERR_Success:    SAFE_PUSH_WSTR(tmp);    netapibufferfree(tmp);    return;       default: -  throw_nt_error("NetGetDCName", ret); +  throw_nt_error(ret);    }   }      /*! @decl string NetGetAnyDCName(string|int(0..0) server, string domain)    *!    *! Get name of a domain controller from a server.    *!    *! @param server    *! Server the domain exists on.    *!
pike.git/src/modules/system/nt.c:2310:    *! @[NetGroupGetUsers()], @[NetLocalGroupGetMembers()],    *! @[NetGetDCName()]    */   void f_NetGetAnyDCName(INT32 args)   {    char *to_free1=NULL,*to_free2=NULL;    BYTE *tmp=0;    LPWSTR server, domain;    NET_API_STATUS ret;    -  check_all_args("NetGetAnyDCName",args,BIT_STRING|BIT_INT, BIT_STRING, 0); +  check_all_args(NULL,args,BIT_STRING|BIT_INT, BIT_STRING, 0);       if(TYPEOF(sp[-args]) == T_STRING)    {    server=(LPWSTR)require_wstring1(sp[-args].u.string,&to_free1);    if(!server) -  Pike_error("NetGetAnyDCName, server name string is too wide.\n"); +  Pike_error("Server name string is too wide.\n");    }else{    server=NULL;    }       domain=(LPWSTR)require_wstring1(sp[1-args].u.string,&to_free2);    if(!domain)    {    if(to_free1) free(to_free1); -  Pike_error("NetGetAnyDCName, domain name string is too wide.\n"); +  Pike_error("Domain name string is too wide.\n");    }       THREADS_ALLOW();    ret=netgetanydcname(server,domain,&tmp);    THREADS_DISALLOW();       pop_n_elems(args);    if(to_free1) free(to_free1);    if(to_free2) free(to_free2);       switch(ret)    {    case NERR_Success:    SAFE_PUSH_WSTR(tmp);    netapibufferfree(tmp);    return;       default: -  throw_nt_error("NetGetAnyDCName", ret); +  throw_nt_error(ret);    }   }      static LPWSTR get_wstring(struct svalue *s)   {    if(TYPEOF(*s) != T_STRING) return (LPWSTR)0;    switch(s->u.string->size_shift)    {    case 0:    {
pike.git/src/modules/system/nt.c:2371:    s->u.string=finish_string_builder(&x);    }    /* Fall through */    case 1:    return STR1(s->u.string);    default:    Pike_error("Bad string width.\n");    /* we never get here, but the "return (LPWSTR)0" makes the compiler    * stop complaining about our not returning a value here.    */ -  return (LPWSTR)0; +  UNREACHABLE(return (LPWSTR)0);    }   }         /* Stuff for NetSessionEnum */      LINKFUNC(NET_API_STATUS, netsessionenum,    (LPWSTR, LPWSTR, LPWSTR, DWORD, LPBYTE *,    DWORD, LPDWORD, LPDWORD, LPDWORD));   
pike.git/src/modules/system/nt.c:2542:    *! This function is only available on some Win32 systems.    *!    */   static void f_NetSessionEnum(INT32 args)   {    LPWSTR server, client, user;    DWORD level;    DWORD resume = 0;    struct array *a=0;    -  check_all_args("System.NetSessionEnum",args, +  check_all_args(NULL,args,    BIT_INT|BIT_STRING,    BIT_INT|BIT_STRING,    BIT_INT|BIT_STRING,    BIT_INT,    0);       server=get_wstring(sp-args);    client=get_wstring(sp-args+1);    user=get_wstring(sp-args+2);    level=sp[3-args].u.integer;       switch (level)    {    case 0: case 1: case 2: case 10: case 502:    /* valid levels */    break;    default: -  Pike_error("NetSessionEnum: Unsupported level: %d.\n", level); +  Pike_error("Unsupported level: %d.\n", level);    }          while(1)    {    DWORD read=0, total=0, e, pos = 0;    NET_API_STATUS ret;    LPBYTE buf=0,ptr;       THREADS_ALLOW();
pike.git/src/modules/system/nt.c:2605:    pos++;    if((INT32)pos>=a->size) break;    ptr+=sizeof_session_info(level);    }    netapibufferfree(buf);    if(ret==ERROR_MORE_DATA) continue;    if(pos < total) continue;    break;       default: -  throw_nt_error("NetSessionEnum", ret); +  throw_nt_error(ret);    }    break;    }   }      /* End netsessionenum */      /*! @decl array(mixed) NetWkstaUserEnum(string|int(0..0) server, int level)    *!    *! @param level
pike.git/src/modules/system/nt.c:2633:    *! This function is only available on some Win32 systems.    *!    */   static void f_NetWkstaUserEnum(INT32 args)   {    LPWSTR server;    DWORD level;    DWORD resume = 0;    struct array *a=0;    -  check_all_args("System.NetWkstaUserEnum",args, +  check_all_args(NULL,args,    BIT_INT|BIT_STRING,    BIT_INT,    0);       server=get_wstring(sp-args);    level=sp[1-args].u.integer;       if (level != 0 && level != 1) -  Pike_error("NetWkstaUserEnum: Unsupported level: %d.\n", level); +  Pike_error("Unsupported level: %d.\n", level);       while(1)    {    DWORD read=0, total=0, e, pos = 0;    NET_API_STATUS ret;    LPBYTE buf=0,ptr;       THREADS_ALLOW();    ret=netwkstauserenum(server,    level,
pike.git/src/modules/system/nt.c:2683:    pos++;    if((INT32)pos>=a->size) break;    ptr+=sizeof_wkstauser_info(level);    }    netapibufferfree(buf);    if(ret==ERROR_MORE_DATA) continue;    if(pos < total) continue;    break;       default: -  throw_nt_error("NetWkstaUserEnum", ret); +  throw_nt_error(ret);    }    break;    }   }    - /*! @decl string normalize_path(string path) + /*! @decl string(8bit) normalize_path(string(8bit) path)    *!    *! Normalize an existing Windows file system path.    *!    *! The following transformations are currently done:    *! @ul    *! @item    *! Forward slashes (@expr{'/'@}) are converted to backward    *! slashes (@expr{'\'@}).    *! @item    *! Trailing slashes are removed, except a single slash after a
pike.git/src/modules/system/nt.c:2740:    *! @note    *! In Pike 7.6 and earlier, this function didn't preserve a single    *! slash after drive letters, and it didn't convert the host and    *! share parts of an UNC path to lowercase.    *!    *! @seealso    *! @[combine_path()], @[combine_path_nt()]    */   static void f_normalize_path(INT32 args)   { -  struct pike_string *str; -  struct string_builder res; -  char *file; -  ONERROR res_uwp, file_uwp; -  DWORD ret; +  char *path = NULL;    -  get_all_args("normalize_path", args, "%S", &str); +  get_all_args("normalize_path", args, "%s", &path);    -  init_string_builder(&res, 0); -  SET_ONERROR (res_uwp, free_string_builder, &res); -  - #ifdef WANT_GETLONGPATHNAME_WRAPPER -  -  file = str->str; -  if (file[str->len - 1] == '/' || file[str->len - 1] == '\\') { -  /* Add a '.' if the path ends with slash(es). This works just as -  * well as removing all trailing slashes (even for files), but it -  * has the benefit that we don't get the cwd when the input is -  * e.g. "c:\\". */ -  file = xalloc(str->len + 2); -  SET_ONERROR (file_uwp, free, file); -  MEMCPY(file, str->str, str->len); -  file[str->len] = '.'; -  file[str->len + 1] = 0; +  path = fd_normalize_path(path); +  if (!path) { +  throw_nt_error(errno);    }    -  ret = str->len; /* Guess that the result will have the same length... */ -  do{ -  string_builder_allocate(&res, ret, 0); -  /* NOTE: Use the emulated GetLongPathName(), since it normalizes all -  * components of the path. -  */ -  ret = Emulate_GetLongPathName(file, res.s->str, res.malloced); -  if (!ret) { -  unsigned long err = GetLastError(); -  set_errno_from_win32_error (err); -  throw_nt_error("normalize_path", err); +  push_text(path); +  free(path);   } -  } while (ret > (size_t) res.malloced); +     -  if (file != str->str) { -  free (file); -  UNSET_ONERROR (file_uwp); -  } -  - #else /* !WANT_GETLONGPATHNAME_WRAPPER */ -  -  /* Haven't got Emulate_GetLongPathName. We essentially do what it -  * does. This appears to be the only reliable way to normalize a -  * path. (GetLongPathName doesn't always correct upper/lower case -  * differences, and opening the file to use e.g. -  * GetFinalPathNameByHandle on it might not work if it's already -  * opened for exclusive access.) */ -  -  /* First convert to an absolute path. */ -  file = xalloc (MAX_PATH); -  SET_ONERROR (file_uwp, free, file); -  ret = GetFullPathName (str->str, MAX_PATH, file, NULL); -  if (ret > MAX_PATH) { -  errno = ENAMETOOLONG; -  throw_nt_error ("normalize_path", ERROR_BUFFER_OVERFLOW); -  } -  if (!ret) { -  unsigned int err = GetLastError(); -  set_errno_from_win32_error (err); -  throw_nt_error ("normalize_path", err); -  } -  -  { -  LPSHELLFOLDER isf; -  LPWSTR wfile; -  ONERROR wfile_uwp; -  size_t l; -  PIDLIST_ABSOLUTE idl; -  HRESULT hres; -  -  if (SHGetDesktopFolder (&isf) != S_OK) -  /* Use a nondescript error code. */ -  throw_nt_error ("normalize_path", errno = ERROR_INVALID_DATA); -  -  l = strlen (file); -  wfile = malloc ((l + 1) * 2); -  if (!wfile) SIMPLE_OUT_OF_MEMORY_ERROR ("normalize_path", (l + 1) * 2); -  SET_ONERROR (wfile_uwp, free, wfile); -  wfile[l] = 0; -  while (l--) wfile[l] = (unsigned char) file[l]; -  -  hres = isf->lpVtbl->ParseDisplayName (isf, NULL, NULL, wfile, -  NULL, &idl, NULL); -  if (hres != S_OK) { -  errno = (HRESULT_FACILITY (hres) == FACILITY_WIN32 ? -  HRESULT_CODE (hres) : -  /* Use a nondescript code if the error isn't a Win32 one. */ -  ERROR_INVALID_DATA); -  throw_nt_error ("normalize_path", errno); -  } -  -  /* FIXME: Detect and handle windows unicode mode. */ -  if (!SHGetPathFromIDList (idl, file)) { -  CoTaskMemFree (idl); -  throw_nt_error ("normalize_path", errno = ERROR_INVALID_DATA); -  } -  ret = strlen (file); -  -  CoTaskMemFree (idl); -  free (wfile); -  UNSET_ONERROR (wfile_uwp); -  } -  -  string_builder_strcat (&res, file); -  -  free (file); -  UNSET_ONERROR (file_uwp); -  - #endif /* !WANT_GETLONGPATHNAME_WRAPPER */ -  -  /* Remove trailing slashes, except after a drive letter. */ -  { -  ptrdiff_t l = (ptrdiff_t) ret - 1; -  file = res.s->str; -  if(l >= 0 && file[l]=='\\') -  { -  do l--; -  while(l && file[l]=='\\'); -  if (l == 1 && file[l] == ':') l++; -  file[l + 1]=0; -  } -  res.s->len = l + 1; -  } -  -  /* Convert host and share in an UNC path to lowercase since Windows -  * Shell doesn't do that consistently. */ -  if (file[0] == '\\' && file[1] == '\\') { -  size_t i; -  for (i = 2; file[i] && file[i] != '\\'; i++) -  file[i] = tolower (file[i]); -  if (file[i] == '\\') -  for (i++; file[i] && file[i] != '\\'; i++) -  file[i] = tolower (file[i]); -  } -  -  pop_n_elems(args); -  push_string(finish_string_builder(&res)); -  UNSET_ONERROR (res_uwp); - } -  +    /*! @decl int GetFileAttributes(string filename)    *!    *! Get the file attributes for the specified file.    *!    *! @note    *! This function is only available on Win32 systems.    *!    *! @seealso    *! @[SetFileAttributes()]    */   static void f_GetFileAttributes(INT32 args)   {    char *file;    DWORD ret; -  VALID_FILE_IO("GetFileAttributes","read"); -  get_all_args("GetFileAttributes",args,"%s",&file); +  get_all_args(NULL, args, "%s", &file);    ret=GetFileAttributes( (LPCTSTR) file);    pop_stack();    errno=GetLastError();    push_int(ret);   }      /*! @decl int SetFileAttributes(string filename)    *!    *! Set the file attributes for the specified file.    *!
pike.git/src/modules/system/nt.c:2923:    *! This function is only available on Win32 systems.    *!    *! @seealso    *! @[GetFileAttributes()]    */   static void f_SetFileAttributes(INT32 args)   {    char *file;    INT_TYPE attr, ret;    DWORD tmp; -  VALID_FILE_IO("SetFileAttributes","write"); -  get_all_args("SetFileAttributes", args, "%s%i", &file, &attr); +  get_all_args(NULL, args, "%s%i", &file, &attr);    tmp=attr;    ret=SetFileAttributes( (LPCTSTR) file, tmp);    pop_stack();    errno=GetLastError();    push_int(ret);   }      /*! @decl array(mixed) LookupAccountName(string|int(0..0) sys, string account)    *!    *! @note
pike.git/src/modules/system/nt.c:2946:    *!    */   static void f_LookupAccountName(INT32 args)   {    LPCTSTR sys=0;    LPCTSTR acc;    DWORD sidlen, domainlen;    SID_NAME_USE tmp;    char buffer[1];    -  check_all_args("LookupAccountName",args,BIT_INT|BIT_STRING, BIT_STRING,0); +  check_all_args(NULL,args,BIT_INT|BIT_STRING, BIT_STRING,0);    if(TYPEOF(sp[-args]) == T_STRING)    {    if(sp[-args].u.string->size_shift != 0) -  Pike_error("LookupAccountName: System name is wide string.\n"); +  Pike_error("System name is wide string.\n");    sys=STR0(sp[-args].u.string);    }    if(sp[1-args].u.string->size_shift != 0) -  Pike_error("LookupAccountName: Account name is wide string.\n"); +  Pike_error("Account name is wide string.\n");       acc=STR0(sp[1-args].u.string);       sidlen=0;    domainlen=0;       /* Find size required */    lookupaccountname(sys,    acc,    (PSID)buffer,    &sidlen,    (LPTSTR)buffer,    &domainlen,    &tmp);       if(sidlen && domainlen)    { -  PSID sid=(PSID)xalloc(sidlen); +  PSID sid=xalloc(sidlen);    struct pike_string *dom=begin_shared_string(domainlen-1);       if(lookupaccountname(sys,    acc,    sid,    &sidlen,    (LPTSTR)(STR0(dom)),    &domainlen,    &tmp))    {    struct object *o;    pop_n_elems(args); -  o=low_clone(sid_program); +  o=fast_clone_object(sid_program);    (*(PSID *)(o->storage))=sid;    push_object(o);    push_string(end_shared_string(dom));    push_int(tmp);    f_aggregate(3);    return;    } -  free((char *)dom); -  free((char *)sid); +  free(dom); +  free(sid);    }    errno=GetLastError();    pop_n_elems(args);    push_array(allocate_array(3));   }         static struct array *encode_acl(PACL acl)   {    ACL_SIZE_INFORMATION tmp;
pike.git/src/modules/system/nt.c:3016:    {    unsigned int e;    check_stack(((ptrdiff_t)(tmp.AceCount + 4)));    for(e=0;e<tmp.AceCount;e++)    {    void *ace;    if(!GetAce(acl, e, &ace)) break;    switch(((ACE_HEADER *)ace)->AceType)    {    case ACCESS_ALLOWED_ACE_TYPE: -  push_constant_text("allow"); +  push_static_text("allow");    push_int(((ACE_HEADER *)ace)->AceFlags);    push_int( ((ACCESS_ALLOWED_ACE *)ace)->Mask );    SAFE_PUSH_SID( & ((ACCESS_ALLOWED_ACE *)ace)->SidStart );    f_aggregate(4);    break;       case ACCESS_DENIED_ACE_TYPE: -  push_constant_text("deny"); +  push_static_text("deny");    push_int(((ACE_HEADER *)ace)->AceFlags);    push_int( ((ACCESS_DENIED_ACE *)ace)->Mask );    SAFE_PUSH_SID( & ((ACCESS_DENIED_ACE *)ace)->SidStart );    f_aggregate(4);    break;       case SYSTEM_AUDIT_ACE_TYPE: -  push_constant_text("audit"); +  push_static_text("audit");    push_int(((ACE_HEADER *)ace)->AceFlags);    push_int( ((SYSTEM_AUDIT_ACE *)ace)->Mask );    SAFE_PUSH_SID( & ((SYSTEM_AUDIT_ACE *)ace)->SidStart );    f_aggregate(4);    break;       default: -  push_constant_text("unknown"); +  push_static_text("unknown");    f_aggregate(1);    break;       }    }    return aggregate_array(e);    }    return 0;   }   
pike.git/src/modules/system/nt.c:3095:    {    case ( 'a' << 8 ) + 'c': size += sizeof(ACCESS_ALLOWED_ACE); break;    case ( 'd' << 8 ) + 'e': size += sizeof(ACCESS_DENIED_ACE); break;    case ( 'a' << 8 ) + 'u': size += sizeof(SYSTEM_AUDIT_ACE); break;    default:    Pike_error("ACE[%d][0] is not a known ACE type.\n");    }    size += getlengthsid( *sid ) - sizeof(DWORD);    }    -  ret=(PACL)xalloc( size ); +  ret=xalloc( size );       if(!initializeacl(ret, size, ACL_REVISION))    Pike_error("InitializeAcl failed!\n");       for(a=0;a<arr->size;a++)    {    str=arr->item[a].u.array->item[0].u.string->str;    sid=(PSID *)get_storage(arr->item[a].u.array->item[3].u.object,sid_program);       switch( ( str[0] << 8 ) + str[1] )
pike.git/src/modules/system/nt.c:3159:    char *name;    struct mapping *m;    SECURITY_INFORMATION flags=0;    PSID owner=0;    PSID group=0;    PACL dacl=0;    PACL sacl=0;    DWORD ret;    SE_OBJECT_TYPE type=SE_FILE_OBJECT;    -  ASSERT_SECURITY_ROOT("SetNamedSecurity"); -  get_all_args("SetNamedSecurityInfo",args,"%s%m",&name,&m); +  get_all_args(NULL, args, "%s%m", &name, &m);    -  if((sval=simple_mapping_string_lookup(m, "type"))) +  if((sval=low_mapping_string_lookup(m, literal_type_string)))    {    if(TYPEOF(*sval) != T_INT) -  Pike_error("Bad 'type' in SetNamedSecurityInfo.\n"); +  Pike_error("Bad 'type' type.\n");    type=sval->u.integer;    }       if((sval=simple_mapping_string_lookup(m,"owner")))    {    if(TYPEOF(*sval) != T_OBJECT ||    !get_storage(sval->u.object, sid_program)) -  Pike_error("Bad 'owner' in SetNamedSecurityInfo.\n"); +  Pike_error("Bad 'owner' type.\n");    owner=*(PSID *)get_storage(sval->u.object, sid_program);    flags |= OWNER_SECURITY_INFORMATION;    }       if((sval=simple_mapping_string_lookup(m,"group")))    {    if(TYPEOF(*sval) != T_OBJECT ||    !get_storage(sval->u.object, sid_program)) -  Pike_error("Bad 'group' in SetNamedSecurityInfo.\n"); +  Pike_error("Bad 'group' type.\n");    group=*(PSID *)get_storage(sval->u.object, sid_program);    flags |= GROUP_SECURITY_INFORMATION;    }       if((sval=simple_mapping_string_lookup(m,"dacl")))    {    if(TYPEOF(*sval) != T_ARRAY) -  Pike_error("Bad 'dacl' in SetNamedSecurityInfo.\n"); +  Pike_error("Bad 'dacl' type.\n");    dacl=decode_acl(sval->u.array);    flags |= DACL_SECURITY_INFORMATION;    }       if((sval=simple_mapping_string_lookup(m,"sacl")))    {    if(TYPEOF(*sval) != T_ARRAY) -  Pike_error("Bad 'sacl' in SetNamedSecurityInfo.\n"); +  Pike_error("Bad 'sacl' type.\n");    sacl=decode_acl(sval->u.array);    flags |= SACL_SECURITY_INFORMATION;    }       /* FIXME, add dacl and sacl!!!! */       ret=setnamedsecurityinfo(name,    type,    flags,    owner,
pike.git/src/modules/system/nt.c:3238:    PSID owner=0, group=0;    PACL dacl=0, sacl=0;    PSECURITY_DESCRIPTOR desc=0;    DWORD ret;    SECURITY_INFORMATION flags=    OWNER_SECURITY_INFORMATION |    GROUP_SECURITY_INFORMATION |    DACL_SECURITY_INFORMATION;       SE_OBJECT_TYPE type = SE_FILE_OBJECT; -  check_all_args("GetSecurityInfo",args,BIT_STRING, BIT_VOID|BIT_INT, BIT_VOID|BIT_INT, 0); +  check_all_args(NULL,args,BIT_STRING, BIT_VOID|BIT_INT, BIT_VOID|BIT_INT, 0);       switch(args)    {    default: flags=sp[2-args].u.integer;    case 2: type=sp[1-args].u.integer;    case 1: break;    }       if(!(ret=getnamedsecurityinfo(sp[-args].u.string->str,    type,
pike.git/src/modules/system/nt.c:3261:    &group,    &dacl,    &sacl,    &desc)))    {    int tmp=0;    pop_n_elems(args);       if(owner)    { -  push_constant_text("owner"); +  push_static_text("owner");    SAFE_PUSH_SID(owner);    tmp++;    }    if(group)    { -  push_constant_text("group"); +  push_static_text("group");    SAFE_PUSH_SID(group);    tmp++;    }    if(sacl)    { -  push_constant_text("sacl"); +  push_static_text("sacl");    push_array( encode_acl( sacl ));    tmp++;    }    if(dacl)    { -  push_constant_text("dacl"); +  push_static_text("dacl");    push_array( encode_acl( dacl ));    tmp++;    }    f_aggregate_mapping(tmp * 2);    }else{    pop_n_elems(args);    push_int(0);    errno=ret; /* magic */    }    if(desc) LocalFree(desc);
pike.git/src/modules/system/nt.c:3313:       pop_n_elems(args);       osversion.dwOSVersionInfoSize=sizeof(osversion);    if(!GetVersionEx(&osversion))    Pike_error("GetVersionEx failed with errno %d\n",GetLastError());       GetSystemInfo(&sysinfo);       n+=2; -  push_text("architecture"); +  push_static_text("architecture");    switch(sysinfo.wProcessorArchitecture)    {    case PROCESSOR_ARCHITECTURE_INTEL:    sprintf(buf, "i%ld", sysinfo.dwProcessorType);    push_text(buf);    machine = "i86pc";    break;       case PROCESSOR_ARCHITECTURE_MIPS: -  push_text("mips"); +  push_static_text("mips");    machine = "mips";    break;       case PROCESSOR_ARCHITECTURE_ALPHA: -  push_text("alpha"); +  push_static_text("alpha");    machine = "alpha";    break;       case PROCESSOR_ARCHITECTURE_PPC: -  push_text("ppc"); +  push_static_text("ppc");    machine = "ppc";    break;      #ifdef PROCESSOR_ARCHITECTURE_SHX    case PROCESSOR_ARCHITECTURE_SHX:    machine = "shx";    switch (sysinfo.dwProcessorType) {    case PROCESSOR_HITACHI_SH3:    case PROCESSOR_SHx_SH3: -  push_text("sh3"); +  push_static_text("sh3");    break;    case PROCESSOR_HITACHI_SH3E: -  push_text("sh3e"); +  push_static_text("sh3e");    break;    case PROCESSOR_HITACHI_SH4:    case PROCESSOR_SHx_SH4: -  push_text("sh4"); +  push_static_text("sh4");    break;    default: -  push_text("shx"); +  push_static_text("shx");    break;    }    break;   #endif /* PROCESSOR_ARCHITECTURE_SHX */      #ifdef PROCESSOR_ARCHITECTURE_ARM    case PROCESSOR_ARCHITECTURE_ARM:    machine = "arm";    switch (sysinfo.dwProcessorType) {    case PROCESSOR_STRONGARM: -  push_text("strongarm"); +  push_static_text("strongarm");    break;    case PROCESSOR_ARM720: -  push_text("arm720"); +  push_static_text("arm720");    break;    case PROCESSOR_ARM820: -  push_text("arm820"); +  push_static_text("arm820");    break;    case PROCESSOR_ARM920: -  push_text("arm920"); +  push_static_text("arm920");    break;    case PROCESSOR_ARM_7TDMI: -  push_text("arm7tdmi"); +  push_static_text("arm7tdmi");    break;    default: -  push_text("arm"); +  push_static_text("arm");    break;    }    break;   #endif /* PROCESSOR_ARCHITECTURE_ARM */    - #ifdef PROCESSOR_ARCHITECTURE_IA64 -  case PROCESSOR_ARCHITECTURE_IA64: -  machine = "ia64"; -  push_text("ia64"); -  break; - #endif /* PROCESSOR_ARCHITECTURE_IA64 */ -  +    #ifdef PROCESSOR_ARCHITECTURE_ALPHA64    case PROCESSOR_ARCHITECTURE_ALPHA64:    machine = "alpha64"; -  push_text("alpha64"); +  push_static_text("alpha64");    break;   #endif /* PROCESSOR_ARCHITECTURE_ALPHA64 */      #ifdef PROCESSOR_ARCHITECTURE_AMD64    case PROCESSOR_ARCHITECTURE_AMD64:    machine = "amd64"; -  push_text("amd64"); +  push_static_text("amd64");    break;   #endif      #ifdef PROCESSOR_ARCHITECTURE_MSIL    case PROCESSOR_ARCHITECTURE_MSIL:    machine = "msil"; -  push_text("msil"); +  push_static_text("msil");    break;   #endif /* PROCESSOR_ARCHITECTURE_MSIL */       default:    case PROCESSOR_ARCHITECTURE_UNKNOWN:    machine = "unknown"; -  push_text("unknown"); +  push_static_text("unknown");    break;    }       n+=2; -  push_text("machine"); +  push_static_text("machine");    push_text(machine);       n+=2; -  push_text("sysname"); +  push_static_text("sysname");    switch(osversion.dwPlatformId)    {    case VER_PLATFORM_WIN32s:    version = "3.1"; -  push_text("Win32s"); +  push_static_text("Win32s");    break;       case VER_PLATFORM_WIN32_WINDOWS: -  push_text("Win32"); +  push_static_text("Win32");    switch(osversion.dwMinorVersion)    {    case 0:    version = "95";    break;    case 10:    version = "98";    break;    case 90:    version = "Me";    break;    }    break;       case VER_PLATFORM_WIN32_NT: -  push_text("Win32"); +  push_static_text("Win32");    switch(osversion.dwMajorVersion)    {    case 3:    version = "NT 3.51";    break;    case 4:    version = "NT 4.0";    break;    case 5:    switch(osversion.dwMinorVersion)
pike.git/src/modules/system/nt.c:3476:    version = "XP";    break;    case 2:    version = "Server 2003";    break;    }    }    break;       default: -  push_text("Win32"); +  push_static_text("Win32");    break;    }    -  SNPRINTF(buf, sizeof(buf), "Windows %s %ld.%ld.%ld", +  snprintf(buf, sizeof(buf), "Windows %s %ld.%ld.%ld",    version,    osversion.dwMajorVersion,    osversion.dwMinorVersion,    osversion.dwBuildNumber & 0xffff);       n+=2; -  push_text("release"); +  push_static_text("release");    push_text(buf);       n+=2; -  push_text("version"); +  push_static_text("version");    push_text(osversion.szCSDVersion);       n+=2; -  push_text("nodename"); +  push_static_text("nodename");    gethostname(buf, sizeof(buf));    push_text(buf);       f_aggregate_mapping(n);   }         /**************************/   /* start Security context */   
pike.git/src/modules/system/nt.c:3540:    CtxtHandle hctxt;    int hctxt_alloced;    TCHAR lpPackageName[1024];    DWORD cbMaxMessage;    BYTE * buf;    DWORD cBuf;    int done;    int lastError;   };    - #define THIS_SCTX ((struct sctx_storage *)Pike_fp->current_storage) + #define THIS_SCTX ((struct sctx_storage *)CURRENT_STORAGE)   static struct program *sctx_program;   static void init_sctx(struct object *o)   {    struct sctx_storage *sctx = THIS_SCTX;       memset(sctx, 0, sizeof(struct sctx_storage));   }      static void exit_sctx(struct object *o)   {
pike.git/src/modules/system/nt.c:3576:         static void f_sctx_create(INT32 args)   {    struct sctx_storage *sctx = THIS_SCTX;    SECURITY_STATUS ss;    PSecPkgInfo pkgInfo;    TimeStamp Lifetime;    char * pkgName;    -  get_all_args("system.SecurityContext->create",args,"%s",&pkgName); +  get_all_args(NULL, args, "%s", &pkgName);       lstrcpy(sctx->lpPackageName, pkgName);    ss = querysecuritypackageinfo ( sctx->lpPackageName, &pkgInfo);       if (!SEC_SUCCESS(ss))    { -  Pike_error("Could not query package info for %s, error 0x%08x\n", +  Pike_error("Could not query package info for %s, error 0x%08x.\n",    sctx->lpPackageName, ss);    }       sctx->cbMaxMessage = pkgInfo->cbMaxToken;    if (sctx->buf)    free(sctx->buf); -  sctx->buf = (PBYTE)malloc(sctx->cbMaxMessage); +  sctx->buf = malloc(sctx->cbMaxMessage);       freecontextbuffer(pkgInfo);       if (sctx->hcred_alloced)    freecredentialshandle (&sctx->hcred);    ss = acquirecredentialshandle (    NULL,    sctx->lpPackageName,    SECPKG_CRED_INBOUND,    NULL,    NULL,    NULL,    NULL,    &sctx->hcred,    &Lifetime);       if (!SEC_SUCCESS (ss))    { -  Pike_error("AcquireCreds failed: 0x%08x\n", ss); +  Pike_error("AcquireCreds failed: 0x%08x.\n", ss);    }    sctx->hcred_alloced = 1; -  -  pop_n_elems(args); -  push_int(0); +    }         BOOL GenServerContext (BYTE *pIn, DWORD cbIn, BYTE *pOut, DWORD *pcbOut,    BOOL *pfDone, BOOL fNewConversation)   {    struct sctx_storage *sctx = THIS_SCTX;    SECURITY_STATUS ss;    TimeStamp Lifetime;    SecBufferDesc OutBuffDesc;
pike.git/src/modules/system/nt.c:3694:    sctx->lastError = ss;    return FALSE;    }    }       *pcbOut = OutSecBuff.cbBuffer;       *pfDone = !((SEC_I_CONTINUE_NEEDED == ss)    || (SEC_I_COMPLETE_AND_CONTINUE == ss));    - /* fprintf(stderr, "AcceptSecurityContext result = 0x%08x\n", ss); */ -  +     return TRUE;      } /* end GenServerContext */         static void f_sctx_gencontext(INT32 args)   {    struct sctx_storage *sctx = THIS_SCTX;    struct pike_string *in;    BOOL new_conversation = 0;    -  check_all_args("system.SecurityContext->gen_context()", args, -  BIT_STRING,0); +  check_all_args(NULL, args, BIT_STRING,0);       in = Pike_sp[-1].u.string;    if (in->size_shift != 0) -  Pike_error("system.SecurityContext->gen_context(): wide strings is not allowed.\n"); +  Pike_error("Wide strings is not allowed.\n");    sctx->cBuf = sctx->cbMaxMessage;    if (!GenServerContext (in->str, in->len, sctx->buf, &sctx->cBuf,    &sctx->done, !sctx->hctxt_alloced))    {    pop_n_elems(args);    push_int(0);    return;    }       pop_n_elems(args);       push_int(sctx->done?1:0);    push_string(make_shared_binary_string(sctx->buf, sctx->cBuf));    f_aggregate(2);   }         static void f_sctx_getlastcontext(INT32 args)   {    struct sctx_storage *sctx = THIS_SCTX; -  check_all_args("system.SecurityContext->get_last_context", args, 0); -  +     pop_n_elems(args);       if (sctx->lastError)    {    push_int(0);    return;    }    push_int(sctx->done?1:0);    push_string(make_shared_binary_string(sctx->buf, sctx->cBuf));    f_aggregate(2);   }         static void f_sctx_isdone(INT32 args)   {    struct sctx_storage *sctx = THIS_SCTX; -  check_all_args("system.SecurityContext->is_done", args, 0); -  +     pop_n_elems(args); -  +     push_int(sctx->done?1:0);   }         static void f_sctx_type(INT32 args)   {    struct sctx_storage *sctx = THIS_SCTX; -  check_all_args("system.SecurityContext->type", args, 0); -  +     pop_n_elems(args); -  +     push_string(make_shared_string(sctx->lpPackageName));   }         static void f_sctx_getusername(INT32 args)   {    struct sctx_storage *sctx = THIS_SCTX;    SECURITY_STATUS ss;    SecPkgContext_Names name;    -  check_all_args("system.SecurityContext->get_username", args, 0); -  +     pop_n_elems(args);       if (!sctx->hctxt_alloced)    {    push_int(0);    return;    }       ss = querycontextattributes(&sctx->hctxt, SECPKG_ATTR_NAMES, &name);    if (ss != SEC_E_OK)
pike.git/src/modules/system/nt.c:3804:       freecontextbuffer(name.sUserName);   }         static void f_sctx_getlasterror(INT32 args)   {    struct sctx_storage *sctx = THIS_SCTX;    LPVOID lpMsgBuf;    char buf[100]; -  check_all_args("system.SecurityContext->last_error", args, 0); +        pop_n_elems(args);       FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |    FORMAT_MESSAGE_FROM_SYSTEM |    FORMAT_MESSAGE_IGNORE_INSERTS,    NULL,    sctx->lastError,    /* Default language */    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
pike.git/src/modules/system/nt.c:3838:    *! Retrieves the NetBIOS name of the local computer.    *!    *! @note    *! This function is Windows specific, and is not available on all systems.    */   static void f_GetComputerName(INT32 args)   {    char name[MAX_COMPUTERNAME_LENGTH + 1];    DWORD len = sizeof(name);    -  check_all_args("system.GetComputerName", args, 0); -  +     pop_n_elems(args);       if (!GetComputerName(name, &len)) -  +  {    push_int(0); -  +  return; +  }       push_string(make_shared_binary_string(name, len));   }      /*! @decl string GetUserName()    *!    *! Retrieves the name of the user associated with the current thread.    *!    *! @note    *! This function is Windows specific, and is not available on all systems.    */   #ifdef HAVE_GETUSERNAME   static void f_GetUserName(INT32 args)   {    char name[UNLEN + 1];    DWORD len = sizeof(name);    -  check_all_args("system.GetUserName", args, 0); -  +     pop_n_elems(args);       if (!GetUserName(name, &len)) -  +  {    push_int(0); -  +  return; +  }       push_string(make_shared_binary_string(name, len-1));   }   #endif /* HAVE_GETUSERNAME */      #define ADD_GLOBAL_INTEGER_CONSTANT(X,Y) \    push_int((long)(Y)); low_add_constant(X,sp-1); pop_stack();   #define SIMPCONST(X) \    add_integer_constant(#X,X,0);   
pike.git/src/modules/system/nt.c:3914:    ADD_FUNCTION("cp",f_cp,tFunc(tStr tStr,tInt), 0);       /* See array hkeys[] above. */       ADD_GLOBAL_INTEGER_CONSTANT("HKEY_CLASSES_ROOT", 0);    ADD_GLOBAL_INTEGER_CONSTANT("HKEY_LOCAL_MACHINE", 1);    ADD_GLOBAL_INTEGER_CONSTANT("HKEY_CURRENT_USER", 2);    ADD_GLOBAL_INTEGER_CONSTANT("HKEY_USERS", 3);      /* function(int,string,string:string|int|string*) */ -  ADD_EFUN("RegGetValue", f_RegGetValue, +  ADD_FUNCTION("RegGetValue", f_RegGetValue,    tFunc(tInt tStr tStr, tOr3(tStr, tInt, tArr(tStr))),    OPT_EXTERNAL_DEPEND);    -  ADD_EFUN("RegGetValues", f_RegGetValues, +  ADD_FUNCTION("RegGetValues", f_RegGetValues,    tFunc(tInt tStr, tMap(tStr, tOr3(tStr, tInt, tArr(tStr)))),    OPT_EXTERNAL_DEPEND);    -  ADD_EFUN("RegGetKeyNames", f_RegGetKeyNames, tFunc(tInt tStr, tArr(tStr)), -  OPT_EXTERNAL_DEPEND); +  ADD_FUNCTION("RegGetKeyNames", f_RegGetKeyNames, +  tFunc(tInt tStr, tArr(tStr)), OPT_EXTERNAL_DEPEND);    -  ADD_FUNCTION2("RegGetValue_76", f_RegGetValue_76, -  tFunc(tInt tStr tStr, tOr3(tStr, tInt, tArr(tStr))), -  0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT); -  -  ADD_FUNCTION2("RegGetValues_76", f_RegGetValues_76, -  tFunc(tInt tStr, tMap(tStr, tOr3(tStr, tInt, tArr(tStr)))), -  0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT); -  -  ADD_FUNCTION2("RegGetKeyNames_76", f_RegGetKeyNames_76, -  tFunc(tInt tStr, tArr(tStr)), -  0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT); -  +    /* function(void:int) */   #ifdef HAVE_FREECONSOLE    ADD_FUNCTION("FreeConsole", f_freeconsole, tFunc(tNone,tInt), 0);   #endif /* HAVE_FREECONSOLE */      /* function(void:int) */   #ifdef HAVE_ALLOCCONSOLE    ADD_FUNCTION("AllocConsole", f_allocconsole, tFunc(tNone,tInt), 0);   #endif /* HAVE_ALLOCCONSOLE */