diff --git a/src/modules/system/nt.c b/src/modules/system/nt.c index a66e857cbbc4d42348da71a575f584d4f1daaeec..a419509e30b16c9641d072bde59d1202a293cc5b 100644 --- a/src/modules/system/nt.c +++ b/src/modules/system/nt.c @@ -1,5 +1,5 @@ /* - * $Id: nt.c,v 1.15 1999/09/01 01:49:19 mast Exp $ + * $Id: nt.c,v 1.16 1999/11/30 23:06:05 hubbe Exp $ * * NT system calls for Pike * @@ -671,6 +671,7 @@ static netgroupenumtype netgroupenum, netlocalgroupenum; static netgroupgetuserstype netgroupgetusers, netlocalgroupgetmembers; static netgetdcnametype netgetdcname, netgetanydcname; static netapibufferfreetype netapibufferfree; + HINSTANCE netapilib; @@ -1506,6 +1507,230 @@ void f_NetGetAnyDCName(INT32 args) } } +static LPWSTR get_wstring(struct svalue *s) +{ + if(s->type != T_STRING) return (LPWSTR)0; + switch(s->u.string->size_shift) + { + case 0: + { + struct string_builder x; + init_string_builder(&x,1); + string_builder_shared_strcat(&x, s->u.string); + string_builder_putchar(&x, 0); + string_builder_putchar(&x, 32767); + free_string(s->u.string); + s->u.string=finish_string_builder(&x); + } + /* Fall through */ + case 1: + return STR1(s->u.string); + case 2: + error("String too wide!\n"); + } +} + + +/* Stuff for NetSessionEnum */ + +LINKFUNC(NET_API_STATUS,netsessionenum, + (LPWSTR, LPWSTR, LPWSTR, DWORD, LPBYTE *, + DWORD, LPDWORD,LPDWORD,LPDWORD)); + + +static void low_encode_session_info_0(SESSION_INFO_0 *tmp) +{ + SAFE_PUSH_WSTR(tmp->sesi0_cname); +} + +static void low_encode_session_info_1(SESSION_INFO_1 *tmp) +{ + SAFE_PUSH_WSTR(tmp->sesi1_cname); + SAFE_PUSH_WSTR(tmp->sesi1_username); + push_int(tmp->sesi1_time); + push_int(tmp->sesi1_idle_time); + push_int(tmp->sesi1_user_flags); + f_aggregate(5); +} + +static void low_encode_session_info_2(SESSION_INFO_2 *tmp) +{ + SAFE_PUSH_WSTR(tmp->sesi2_cname); + SAFE_PUSH_WSTR(tmp->sesi2_username); + push_int(tmp->sesi2_num_opens); + push_int(tmp->sesi2_time); + push_int(tmp->sesi2_idle_time); + push_int(tmp->sesi2_user_flags); + SAFE_PUSH_WSTR(tmp->sesi2_cltype_name); + + f_aggregate(7); +} + +static void low_encode_session_info_10(SESSION_INFO_10 *tmp) +{ + SAFE_PUSH_WSTR(tmp->sesi10_cname); + SAFE_PUSH_WSTR(tmp->sesi10_username); + push_int(tmp->sesi10_time); + push_int(tmp->sesi10_idle_time); + + f_aggregate(4); +} + +static void low_encode_session_info_502(SESSION_INFO_502 *tmp) +{ + SAFE_PUSH_WSTR(tmp->sesi502_cname); + SAFE_PUSH_WSTR(tmp->sesi502_username); + push_int(tmp->sesi502_num_opens); + + push_int(tmp->sesi502_time); + push_int(tmp->sesi502_idle_time); + push_int(tmp->sesi502_user_flags); + + SAFE_PUSH_WSTR(tmp->sesi502_cltype_name); + SAFE_PUSH_WSTR(tmp->sesi502_transport); + + f_aggregate(8); +} + + +static void encode_session_info(BYTE *u, int level) +{ + if(!u) + { + push_int(0); + return; + } + switch(level) + { + case 0: low_encode_session_info_0 ((SESSION_INFO_0 *) u);break; + case 1: low_encode_session_info_1 ((SESSION_INFO_1 *) u); break; + case 2: low_encode_session_info_2 ((SESSION_INFO_2 *) u);break; + case 10:low_encode_session_info_10((SESSION_INFO_10 *)u); break; + case 502:low_encode_session_info_502((SESSION_INFO_502 *)u); break; + default: + error("Unsupported SESSIONINFO level.\n"); + } +} + +static int sizeof_session_info(int level) +{ + switch(level) + { + case 0: return sizeof(SESSION_INFO_0); + case 1: return sizeof(SESSION_INFO_1); + case 2: return sizeof(SESSION_INFO_2); + case 10: return sizeof(SESSION_INFO_10); + case 502: return sizeof(SESSION_INFO_502); + default: return -1; + } +} + +static void f_NetSessionEnum(INT32 args) +{ + INT32 pos=0,e; + LPWSTR server, client, user; + DWORD level; + DWORD resume = 0; + struct array *a=0; + + check_all_args("System.NetSessionEnum",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) + { + default: + error("System.NetSessionEnum: Unsupported level.\n"); + + case 0: + case 1: + case 2: + case 10: + case 502: + break; + } + + + while(1) + { + DWORD read=0, total=0; + NET_API_STATUS ret; + LPBYTE buf=0,ptr; + + THREADS_ALLOW(); + ret=netsessionenum(server, + client, + user, + level, + &buf, + 0x10000, + &read, + &total, + &resume); + THREADS_DISALLOW(); + + if(!a) + push_array(a=allocate_array(total)); + + switch(ret) + { + case ERROR_ACCESS_DENIED: + case ERROR_LOGON_FAILURE: /* Known to be returned sometimes.. */ + error("NetSessionEnum: Access denied.\n"); + break; + + case ERROR_INVALID_PARAMETER: + error("NetSessionEnum: Invalid parameter.\n"); + + case ERROR_NOT_ENOUGH_MEMORY: + error("NetSessionEnum: Out of memory.\n"); + + case NERR_InvalidComputer: + error("NetSessionEnum: Invalid computer.\n"); + break; + + case NERR_UserNotFound: + error("NetSessionEnum: User not found\n"); + break; + + case NERR_ClientNameNotFound: + error("NetSessionEnum: Client name not found.\n"); + break; + + case NERR_Success: + case ERROR_MORE_DATA: + ptr=buf; + for(e=0;e<read;e++) + { + encode_session_info(ptr,level); + a->item[pos]=sp[-1]; + sp--; + pos++; + if(pos>=a->size) break; + ptr+=sizeof_session_info(level); + } + netapibufferfree(buf); + if(ret==ERROR_MORE_DATA) continue; + if(pos < total) continue; + break; + + default: + error("NetUserEnum: Unknown error %d\n",ret); + } + break; + } +} + +/* End netsessionenum */ + static void f_GetFileAttributes(INT32 args) { char *file; @@ -2111,6 +2336,18 @@ void init_nt_system_calls(void) add_function("NetGetAnyDCName",f_NetGetAnyDCName,"function(string|int,string:string)",0); } + + + /* FIXME: On windows 9x, netsessionenum is located in svrapi.lib */ + if(proc=GetProcAddress(netapilib, "NetSessionEnum")) + { + netsessionenum=(netsessionenumtype)proc; + + add_function("NetSessionEnum",f_NetSessionEnum,"function(string,string,string,int:array(int|string))",0); + + SIMPCONST(SESS_GUEST); + SIMPCONST(SESS_NOENCRYPTION); + } } } } diff --git a/src/modules/system/testsuite.in b/src/modules/system/testsuite.in index e6ed17501306162fa037a42bfb244ed9a10ba895..c1bd72a3d84c57f8e2f7adae0be668061d661084 100644 --- a/src/modules/system/testsuite.in +++ b/src/modules/system/testsuite.in @@ -1,4 +1,4 @@ -// $Id: testsuite.in,v 1.11 1999/03/12 17:49:52 mast Exp $ +// $Id: testsuite.in,v 1.12 1999/11/30 23:06:06 hubbe Exp $ // system.c: @@ -145,3 +145,8 @@ cond([[ all_constants()->getpwuid && all_constants()->getpwnam ]], [[ // closelog HAVE_SYSLOG // openlog HAVE_SYSLOG // syslog HAVE_SYSLOG + +cond([[ system->NetSessionEnum ]], +[[ + test_true( system.NetSessionEnum(0,0,0,0) ) +]]) \ No newline at end of file