1/*$Header: /p/tcsh/cvsroot/tcsh/win32/nt.who.c,v 1.6 2006/03/05 08:59:36 amold Exp $*/ 2/*- 3 * Copyright (c) 1980, 1991 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the University nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31/* 32 * nt.who.c: Support for who-like functions, using NETBIOS 33 * -amol 34 * 35 */ 36#define WIN32_LEAN_AND_MEAN 37#include <windows.h> 38#include <nb30.h> 39#include <stdio.h> 40#include "sh.h" 41 42 43typedef struct _ASTAT_ { 44 ADAPTER_STATUS adapt; 45 NAME_BUFFER NameBuff [10]; 46} ASTAT; 47 48typedef struct _n_ctx { 49 NCB ncb; 50 u_char usr_name[NCBNAMSZ]; 51 u_char mach_name[NCBNAMSZ]; 52} ncb_ctx; 53 54typedef UCHAR (APIENTRY *netbios_func)(NCB *); 55 56 57static netbios_func p_Netbios =0; 58static int ginited = 0; 59 60static CRITICAL_SECTION nb_critter; 61static HMODULE hnetapi; 62 63 64extern int add_to_who_list(u_char *,u_char*); 65 66void init_netbios(void ) { 67 68 69 if (!ginited) { 70 hnetapi = LoadLibrary("NETAPI32.DLL"); 71 if (!hnetapi) 72 return ; 73 74 p_Netbios = (netbios_func)GetProcAddress(hnetapi,"Netbios"); 75 76 if (!p_Netbios ) 77 return ; 78 ginited = 1; 79 } 80 InitializeCriticalSection(&nb_critter); 81} 82void cleanup_netbios(void) { 83 if (hnetapi){ 84 DeleteCriticalSection(&nb_critter); 85 FreeLibrary(hnetapi); 86 } 87} 88void CALLBACK complete_ncb( NCB * p_ncb) { 89 90 int count,i; 91 ADAPTER_STATUS *p_ad; 92 ASTAT *pas; 93 char *p1; 94 ncb_ctx *ctx = (ncb_ctx *)p_ncb; 95 96 if (p_ncb->ncb_retcode) 97 goto end; 98 99 __try { 100 101 EnterCriticalSection(&nb_critter); 102 pas = ((ASTAT*) p_ncb->ncb_buffer); 103 p_ad = &pas->adapt; 104 105 count = p_ad->name_count; 106 107 if (count <=0 ) 108 __leave; 109 110 if (ctx->usr_name[0] == 0) { //any user on given machine 111 for(i=0; i<count;i++) { 112 if (pas->NameBuff[i].name[15] == 03) { // unique name 113 if (!strncmp((char*)(pas->NameBuff[i].name), 114 (char*)(p_ncb->ncb_callname), 115 NCBNAMSZ)) { 116 continue; 117 } 118 else { 119 p1 = strchr((char*)(pas->NameBuff[i].name),' '); 120 if (p1) 121 *p1 = 0; 122 else 123 pas->NameBuff[i].name[15]= 0; 124 add_to_who_list(pas->NameBuff[i].name, 125 ctx->mach_name); 126 break; 127 } 128 } 129 } 130 } 131 else if (ctx->mach_name[0] == 0) { // given user on any machine 132 for(i=0; i<count;i++) { 133 if (pas->NameBuff[i].name[15] == 03) { // unique name 134 if (!strncmp((char*)(pas->NameBuff[i].name), 135 (char*)(p_ncb->ncb_callname), 136 NCBNAMSZ)) 137 continue; 138 else { 139 p1 = strchr((char*)(pas->NameBuff[i].name),' '); 140 if (p1) 141 *p1 = 0; 142 else 143 pas->NameBuff[i].name[15]= 0; 144 145 add_to_who_list(ctx->usr_name, pas->NameBuff[i].name); 146 147 break; 148 } 149 } 150 } 151 } 152 else { // specific user on specific machine 153 for(i=0; i<count;i++) { 154 if (pas->NameBuff[i].name[15] == 03) { // unique name 155 // skip computer name 156 if (!strncmp((char*)(pas->NameBuff[i].name), 157 (char*)(p_ncb->ncb_callname), 158 NCBNAMSZ)) { 159 continue; 160 } 161 else if (!strncmp((char*)(pas->NameBuff[i].name), 162 (char*)(ctx->usr_name), 163 lstrlen((char*)ctx->usr_name))) { 164 p1 = strchr((char*)pas->NameBuff[i].name,' '); 165 if (p1) 166 *p1 = 0; 167 else 168 pas->NameBuff[i].name[15]= 0; 169 add_to_who_list(pas->NameBuff[i].name,ctx->mach_name); 170 break; 171 } 172 } 173 } 174 } 175 } 176 __except(GetExceptionCode()) { 177 ; 178 } 179 LeaveCriticalSection(&nb_critter); 180end: 181 heap_free(p_ncb->ncb_buffer); 182 heap_free(p_ncb); 183 return; 184} 185void start_ncbs (Char **vp) { 186 187 ncb_ctx * p_ctx; 188 NCB *Ncb; 189 Char **namevec = vp; 190 char *p1,*p2,*nb_name; 191 UCHAR uRetCode; 192 ASTAT *Adapter; 193 194 if (!ginited) { 195 init_netbios(); 196 } 197 if (!ginited) 198 return; 199 200 for (namevec = vp;*namevec != NULL;namevec +=2) { 201 202 p_ctx = heap_alloc(sizeof(ncb_ctx)); 203 Adapter = heap_alloc(sizeof(ASTAT)); 204 205 Ncb = (NCB*)p_ctx; 206 207 memset( Ncb, 0, sizeof(NCB) ); 208 209 Ncb->ncb_command = NCBRESET; 210 Ncb->ncb_lana_num = 0; 211 212 uRetCode = p_Netbios( Ncb ); 213 214 if(uRetCode) 215 goto cleanup; 216 217 if ((**namevec == '\0' ) || ( *(namevec +1) == NULL) || 218 (**(namevec +1) == '\0') ) 219 break; 220 221 222 p1 = short2str(*namevec); 223 if (!_stricmp(p1,"any") ) { 224 p_ctx->usr_name[0] = 0; 225 } 226 else { 227 StringCbCopy((char*)p_ctx->usr_name,sizeof(p_ctx->usr_name),p1); 228 } 229 p1 = (char*)&(p_ctx->usr_name[0]); 230 231 p2 = short2str(*(namevec+1)); 232 // 233 // If machine is not "any", make it the callname 234 // 235 if (!_stricmp(p2,"any") ) { 236 p_ctx->mach_name[0] = 0; 237 nb_name = p1; 238 } 239 else { 240 StringCbCopy((char*)p_ctx->mach_name,sizeof(p_ctx->mach_name),p2); 241 nb_name = p2; 242 } 243 244 // do not permit any any 245 // 246 if( (p_ctx->mach_name[0] == 0) && (p_ctx->usr_name[0] == 0) ) 247 goto cleanup; 248 249 250 251 memset( Ncb, 0, sizeof (NCB) ); 252 253 Ncb->ncb_command = NCBASTAT | ASYNCH; 254 Ncb->ncb_lana_num = 0; 255 256 memset(Ncb->ncb_callname,' ',sizeof(Ncb->ncb_callname)); 257 258 Ncb->ncb_callname[15]=03; 259 260 memcpy(Ncb->ncb_callname,nb_name,lstrlen(nb_name)); 261 262 Ncb->ncb_buffer = (u_char *) Adapter; 263 Ncb->ncb_length = sizeof(*Adapter); 264 265 Ncb->ncb_post = complete_ncb; 266 267 uRetCode = p_Netbios( Ncb ); 268 } 269 return; 270 271cleanup: 272 heap_free(Adapter); 273 heap_free(p_ctx); 274 return; 275} 276