int zellvd_rem_init(struct sis1100_softc* sc, int reset) { /* sc->sem_hw must be held by caller!*/ #define MIN_FV_1 1 #define MAX_FV_1 17 #define MIN_FV_2 17 #define MAX_FV_2 17 #define MIN_FV_3 1 #define MAX_FV_3 1 int min_fv=0, max_fv=0; u_int32_t hv, fk, fv; hv=(sc->remote_ident>>8)&0xff; fk=(sc->remote_ident>>16)&0xff; fv=(sc->remote_ident>>24)&0xff; switch (sc->remote_ident&0x00ffff00) { case 0x00010100: /* LVD controller with F1 */ min_fv=MIN_FV_1; max_fv=MAX_FV_1; break; case 0x00010200: /* LVD controller with GPX */ min_fv=MIN_FV_2; max_fv=MAX_FV_2; break; case 0x00010300: /* LVD controller with both F1 and GPX */ min_fv=MIN_FV_3; max_fv=MAX_FV_3; break; default: pERROR(sc, "zellvd: remote hw/fw type not supported"); return -1; } if (fv<min_fv) { pERROR(sc, "zellvd: remote firmware version too old;" " at least version %d is required.", min_fv); return -1; } if (fv>max_fv) { pINFO(sc, "zellvd: Driver not tested with" " remote firmware versions higher than %d.", max_fv); } if (reset>0) lvd_writeremreg(sc, cr, 0, 1); /* reset cr */ return 0; }
/* static */ INT_PTR HookedLoggedOutSAS::MicrosoftDialogProcWrapper(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { if(s_hookedDlgProc == 0) { pERROR(L"HookedLoggedOutSAS::MicrosoftDialogProcWrapper: Dialog wrapper called before we know who we're hooking!"); return 0; // Nothin we can do! } // Fall through if hooking is not enabled if(!s_hookingEnabled) return s_hookedDlgProc(hwnd, msg, wparam, lparam); // Hooking is on, so we let msgina do its thing INT_PTR msginaResult = s_hookedDlgProc(hwnd, msg, wparam, lparam); // If we're init'ing, then we set username, password and queue a message to login if(msg == WM_INITDIALOG) { std::wstring domainUsername = s_loginResult.Domain(); domainUsername += L"\\"; domainUsername += s_loginResult.Username(); pDEBUG(L"HookedLoggedOutSAS::MicrosoftDialogProcWrapper: Hooked dialog, setting username/password and submitting for user: %s", domainUsername.c_str()); SetDlgItemText(hwnd, IDC_MSGINA_USERNAME, domainUsername.c_str()); SetDlgItemText(hwnd, IDC_MSGINA_PASSWORD, s_loginResult.Password().c_str()); SendMessage(hwnd, WM_COMMAND, 1, 1); } return msginaResult; }
GinaChain::GinaChain(WinlogonInterface *pWinLogonIface) : Gina(pWinLogonIface), WinlogonProxy(pWinLogonIface), m_passthru(false) { // Are we in passthru mode? m_passthru = pGina::Registry::GetBool(L"GinaPassthru", false); // When we use the winlogon router table, we want it to // direct all winlogon calls to us (via our WinlogonProxy // implementation). We sit between winlogon and a real // GINA, so our Gina interface let's us have first shot // at Winlogon->Gina direction calls, and WinlogonRouter+ // WinlogonProxy let's us have first shot at Gina->Winlogon // direction traffic. WinlogonRouter::Interface(this); // Init and load our chained/wrapped gina std::wstring ginaName = pGina::Registry::GetString(L"ChainedGinaPath", L"MSGINA.DLL"); pDEBUG(L"Wrapping gina: %s", ginaName.c_str()); m_wrappedGina = new GinaWrapper(ginaName.c_str()); if(!m_wrappedGina->Load()) { pERROR(L"Failed to load wrapped gina: 0x%08x", GetLastError()); return; } // Now negotiate and initialize our wrapped gina if(!m_wrappedGina->Negotiate(WinlogonInterface::Version())) { pERROR(L"Failed to negotiate with wrapped gina using version: %d (0x%08x)", WinlogonInterface::Version(), WinlogonInterface::Version()); return; } if(!m_wrappedGina->Initialize(L"Winsta0", WinlogonRouter::Interface(), NULL, WinlogonRouter::DispatchTable())) { pERROR(L"Failed to initialize wrapped gina"); return; } }
static int _sis1100_write(struct sis1100_softc* sc, struct sis1100_fdata* fd, size_t count, size_t* count_written, u_int32_t addr, const char __user *data) { int32_t am; int datasize; int space, fifo; int res; #if 0 pERROR(sc, "sis1100_write data=%p addr=%08x count=%llu size=%d", data, addr, (unsigned long long)count, fd->vmespace_datasize); #endif switch (fd->subdev) { case sis1100_subdev_ram: am=-1; datasize=4; space=6; fifo=0; break; case sis1100_subdev_remote: am=fd->vmespace_am; datasize=fd->vmespace_datasize; space=1; fifo=fd->fifo_mode; break; case sis1100_subdev_dsp: am=-1; datasize=4; space=6; fifo=0; break; case sis1100_subdev_ctrl: return sis1100_write_irq(sc, fd, count, count_written, data); default: return ENOTTY; } if (count%datasize) return EINVAL; res=sis1100_write_block(sc, fd, datasize, fifo, count/datasize, count_written, space, am, addr, data, &fd->last_prot_err); *count_written*=datasize; return res; }
IFACEMETHODIMP Provider::GetFieldDescriptorCount(__out DWORD* pdwCount) { // # of fields depends on our usage scenario: switch(m_usageScenario) { case CPUS_LOGON: case CPUS_CREDUI: *pdwCount = LUIFI_NUM_FIELDS; return S_OK; case CPUS_UNLOCK_WORKSTATION: *pdwCount = LOIFI_NUM_FIELDS; return S_OK; default: pERROR(L"Provider::GetFieldDescriptorCount: No UI known for the usage scenario: 0x%08x", m_usageScenario); return S_FALSE; } // Should never reach this assert(0); return S_FALSE; }
static void _sis1100_irq_thread(struct sis1100_softc* sc, enum handlercomm command) { u_int32_t new_irqs=0; int i; mutex_lock(&sc->sem_irqinfo); if (command&handlercomm_doorbell) { DECLARE_SPINLOCKFLAGS(flags) u_int32_t doorbell; SPIN_LOCK_IRQSAVE(sc->lock_doorbell, flags); doorbell=sc->doorbell; sc->doorbell=0; SPIN_UNLOCK_IRQRESTORE(sc->lock_doorbell, flags); switch (sc->remote_hw) { case sis1100_hw_vme: new_irqs|=sis3100rem_irq_handler(sc, doorbell); break; case sis1100_hw_camac: new_irqs|=sis5100rem_irq_handler(sc, doorbell); break; case sis1100_hw_pci: /* do nothing */ break; case sis1100_hw_lvd: new_irqs|=zellvd_rem_irq_handler(sc, doorbell); break; case sis1100_hw_pandapixel: new_irqs|=pandapixel_rem_irq_handler(sc, doorbell); break; case sis1100_hw_psf4ad: /* do nothing */ case sis1100_hw_invalid: /* do nothing */ break; } } if (command&handlercomm_lemo) { new_irqs|=sis1100_lemo_handler(sc); } if (command&handlercomm_mbx0) { new_irqs|=sis1100_mbox0_handler(sc); } /* this is called from sis1100_link_up_handler for both 'UP' and 'DOWN' of link one second after status change */ if (command&handlercomm_up) { new_irqs|=sis1100_synch_handler(sc); } if (command&handlercomm_ddma) { new_irqs|=sis1100_ddma_handler(sc); } sc->pending_irqs|=new_irqs; mutex_unlock(&sc->sem_irqinfo); /* inform processes via signal if requested */ mutex_lock(&sc->sem_fdata); for (i=0; i<sis1100_MINORUTMASK+1; i++) { if (sc->fdata[i]) { struct sis1100_fdata* fd=sc->fdata[i]; if (fd->sig>0 && ((new_irqs & fd->owned_irqs)|| (fd->old_remote_hw!=sc->remote_hw))) { int res; /* XXXY muss raus */ pERROR(sc, "irq_pending=%d pending_irqs=0x%x", irq_pending(sc, fd, fd->owned_irqs), sc->pending_irqs); pERROR(sc, "sig=%d new_irqs=0x%x owned_irqs=0x%x", fd->sig, new_irqs, fd->owned_irqs); pERROR(sc, "old_remote_hw=%d remote_hw=%d", fd->old_remote_hw, sc->remote_hw); /* XXXY muss raus */ pERROR(sc, "send sig to %d", pid_nr(fd->pid)); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) res=kill_proc(fd->pid, fd->sig, 1); #else res=kill_pid(fd->pid, fd->sig, 1); #endif if (res) pINFO(sc, "send sig %d to %u: res=%d", fd->sig, pid_nr(fd->pid), res); } } } mutex_unlock(&sc->sem_fdata); /* wake up processes waiting in sis1100_irq_wait or doing select */ #ifdef __NetBSD__ wakeup(&sc->remoteirq_wait); selwakeup(&sc->sel); #elif __linux__ wake_up_interruptible(&sc->remoteirq_wait); #endif }
int #else void #endif sis1100_irq_thread(void* data) { struct sis1100_softc* sc=(struct sis1100_softc*)data; enum handlercomm command; DECLARE_SPINLOCKFLAGS(flags); #ifdef __linux__ #if LINUX_VERSION_CODE < 0x20600 daemonize(); snprintf(current->comm, sizeof(current->comm), "sis1100_%02d", sc->unit); SPIN_LOCK_IRQSAVE(current->sigmask_lock, flags); sigemptyset(¤t->blocked); recalc_sigpending(current); SPIN_UNLOCK_IRQRESTORE(current->sigmask_lock, flags); #endif #endif /*__linux__*/ while (1) { #ifdef __NetBSD__ tsleep(&sc->handler_wait, PCATCH, "thread_vmeirq", 0); #elif __linux__ /* prepare to sleep */ __set_current_state(TASK_INTERRUPTIBLE); /* don't sleep if command!=0 */ if (sc->handlercommand.command) __set_current_state(TASK_RUNNING); else schedule(); #endif if (kthread_should_stop()) return 0; SPIN_LOCK_IRQSAVE(sc->handlercommand.lock, flags); command=sc->handlercommand.command; sc->handlercommand.command=0; SPIN_UNLOCK_IRQRESTORE(sc->handlercommand.lock, flags); #if 0 pERROR(sc, "irq_thread: command=0x%x", command); #endif _sis1100_irq_thread(sc, command); #ifdef __linux__ if (signal_pending (current)) { SPIN_LOCK_IRQSAVE(current->SIGMASK_LOCK, flags); flush_signals(current); SPIN_UNLOCK_IRQRESTORE(current->SIGMASK_LOCK, flags); } #endif /*__linux__*/ } #ifdef __linux__ return 0; #endif }
int sis1100_read_loop( struct sis1100_softc* sc, struct sis1100_fdata* fd, u_int32_t addr, /* VME or SDRAM address */ int32_t am, /* address modifier, not used if <0 */ int size, /* datasize (bytes/word) */ int space, /* remote space (1,2: VME; 6: SDRAM) */ int fifo_mode, size_t count, /* words (of size 'size') to be transferred */ /* count==0 is illegal */ size_t* count_read, /* words transferred */ u_int8_t* data, /* destination (user virtual address) */ int* prot_error ) { u_int32_t head; int idx, res=0; #if 0 pERROR(sc, "read_loop size=%d count=%llu addr=%08x", size, (unsigned long long)count, addr); #endif *count_read=count; head=0x00000002|(space&0x3f)<<16; mutex_lock(&sc->sem_hw); if (am>=0) { head|=0x800; sis1100writereg(sc, t_am, am); } switch (size) { case 1: for (idx=0; idx<count; idx++, data++) { u_int32_t val; sis1100writereg(sc, t_hdr, head|(0x01000000<<(addr&3))); sis1100writereg(sc, t_adl, addr); do { *prot_error=sis1100readreg(sc, prot_error); } while (*prot_error==0x005); if (*prot_error) { *count_read=idx; break; } val=sis1100rawreadreg(sc, tc_dal); #if defined(__LITTLE_ENDIAN) __put_user((val>>((addr&3)<<3))&0xff, (u_int8_t*)(data)); #else __put_user((val>>((3-(addr&3))<<3))&0xff, (u_int8_t*)(data)); #endif if (!fifo_mode) addr++; } break; case 2: for (idx=0; idx<count; idx++, data+=2) { u_int32_t val; sis1100writereg(sc, t_hdr, head|(0x03000000<<(addr&3))); sis1100writereg(sc, t_adl, addr); do { *prot_error=sis1100readreg(sc, prot_error); } while (*prot_error==0x005); if (*prot_error) { *count_read=idx; break; } val=sis1100rawreadreg(sc, tc_dal); #if defined(__LITTLE_ENDIAN) __put_user((val>>((addr&2)<<3))&0xffff, (u_int16_t*)data); #else __put_user((val>>((2-(addr&2))<<3))&0xffff, (u_int16_t*)data); #endif if (!fifo_mode) addr+=2; } break; case 4: sis1100writereg(sc, t_hdr, head|0x0f000000); for (idx=0; idx<count; idx++, data+=4) { u_int32_t val; sis1100writereg(sc, t_adl, addr); do { *prot_error=sis1100readreg(sc, prot_error); } while (*prot_error==0x005); if (*prot_error) { *count_read=idx; break; } val=sis1100rawreadreg(sc, tc_dal); __put_user(val, (u_int32_t*)data); if (!fifo_mode) addr+=4; } break; } mutex_unlock(&sc->sem_hw); return res; }
/* Initialize the fake registry. */ void InitializeFakeRegistry(void) { /* There must be a better way of doing this: */ char row[10*1024], key[10*1024], value[10*1024]; FILE *f_ptr; int i; /* Initialize fake registry linked list. */ reg_head_ptr = reg_tail_ptr = NULL; /* Load a previously saved fake registry (if this fails we assume one * does not yet exist and leave creating one up to the save function). */ if ( GetUserConfigPath(reg_file, FR_FILENAME_LEN) == NULL) return; /* Append filename of registry to path. */ strcat(reg_file, REG_FILENAME); /* Test file, quit if does not exist (first time beebem ran so * no entries). */ if ( (f_ptr=fopen(reg_file, "r")) == NULL) return; /* Load existing registry */ while (fgets( row, 256, f_ptr ) != NULL){ i = strlen(row) -1; while(i>=0){ if (row[i]<32) row[i] = '\0'; i--; } if (strlen(row)<=0) continue; if (row[0] == '#') continue; for(i=0; i< (int) strlen(row); i++) if (row[i] == '#'){ row[i]='\0'; break; } i = strlen(row) -1; while(i>=0){ if (row[i] == '=') break; i--; } if (i<=0) continue; memcpy(key, row, i); key[i]='\0'; value[0] = '\0'; if(strlen(row)-i-1>0){ memcpy(value, row+i+1, strlen(row)-i-1); value[strlen(row)-i-1] = '\0'; } i = strlen(value) -1; while(value[i]<=32 && i>=0){ value[i] = '\0'; i--; } if (SetFakeRegistryItem(key, value) != TRUE) pERROR(dL"Failed to add '%s' to the registry!\n", dR , key); } fclose(f_ptr); }
// SAS handling int GinaChain::LoggedOutSAS(DWORD dwSasType, PLUID pAuthenticationId, PSID pLogonSid, PDWORD pdwOptions, PHANDLE phToken, PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID *pProfile) { // If configured to pass through to MS GINA, or auto-logon is enabled, we // pass through, and let the MS GINA handle the logon. if(m_passthru || IsAutoLogonEnabled()) { return m_wrappedGina->LoggedOutSAS(dwSasType, pAuthenticationId, pLogonSid, pdwOptions, phToken, pMprNotifyInfo, pProfile); } // We auth'd in another session - this session is the real one though, need to tell the service to add! if(dwSasType == WLX_SAS_TYPE_AUTHENTICATED) { // We could do this, but we don't get password (without additional wrapping of our own in WlxGetConsoleSwitchCredentials // So instead we grab it post SAS processing via msgina. WLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 credInfo; if(m_winlogon->WlxQueryConsoleSwitchCredentials(&credInfo)) { pDEBUG(L"LoggedOutSAS: CredInfo=%p PrivateDataLen: 0x%08x PrivateData: %p", &credInfo, credInfo.PrivateDataLen, credInfo.PrivateData); } int msresult = m_wrappedGina->LoggedOutSAS(dwSasType, pAuthenticationId, pLogonSid, pdwOptions, phToken, pMprNotifyInfo, pProfile); //pGina::Transactions::LoginInfo::Add(pMprNotifyInfo->pszUserName, pMprNotifyInfo->pszDomain, pMprNotifyInfo->pszPassword); return msresult; } // Gather username/password from user. If remote, we get it from rdp client if provided, // otherwise show the logged out sas dialog to get it. std::wstring username; std::wstring password; std::wstring domain; bool showDialog = true; if(pGina::Helpers::UserIsRemote()) { WLX_CLIENT_CREDENTIALS_INFO_V2_0 creds; creds.dwType = WLX_CREDENTIAL_TYPE_V2_0; if(m_winlogon->WlxQueryTsLogonCredentials(&creds)) { if(creds.pszUserName) username = creds.pszUserName; if(creds.pszPassword) password = creds.pszPassword; if(creds.pszDomain) domain = creds.pszDomain; if(!creds.fPromptForPassword) showDialog = false; pDEBUG(L"fPromptForPassword: %s", creds.fPromptForPassword ? L"TRUE" : L"FALSE"); pDEBUG(L"fDisconnectOnLogonFailure: %s", creds.fDisconnectOnLogonFailure ? L"TRUE" : L"FALSE"); } } if(showDialog) { DialogLoggedOutSAS dialog(m_winlogon); dialog.Username(username); dialog.Password(password); int dialogResult = dialog.ShowDialog(); if(dialogResult == DialogLoggedOutSAS::SAS_ACTION_LOGON) { // Harvest u/p for passing along to msgina username = dialog.Username(); password = dialog.Password(); } else if(dialogResult >= DialogLoggedOutSAS::SAS_ACTION_MIN && dialogResult <= DialogLoggedOutSAS::SAS_ACTION_MAX) { // Just do as told return dialogResult; } else { // Unknown ret value, default to no action return DialogLoggedOutSAS::SAS_ACTION_NONE; } } // We now have the login info, let's give it a shot! pDEBUG(L"GinaChain::LoggedOutSAS: Processing login for %s", username.c_str()); pGina::Transactions::User::LoginResult result = pGina::Transactions::User::ProcessLoginForUser(username.c_str(), NULL, password.c_str(), pGina::Protocol::LoginRequestMessage::Login); if(!result.Result()) { std::wstring failureMsg = result.Message(); pERROR(L"GinaChain::LoggedOutSAS: %s", failureMsg.c_str()); m_winlogon->WlxMessageBox(NULL, const_cast<wchar_t *>(failureMsg.c_str()), L"Login Failure", MB_ICONEXCLAMATION | MB_OK); return WLX_SAS_ACTION_NONE; } pDEBUG(L"inaChain::LoggedOutSAS: Successful, resulting username: %s", result.Username().c_str()); // Invoke the msgina logged out sas dialog, intercept it, set username/password, and hit ok! HookedLoggedOutSAS::Enabled(true); HookedLoggedOutSAS::SetLoginInfo(result); int msresult = m_wrappedGina->LoggedOutSAS(dwSasType, pAuthenticationId, pLogonSid, pdwOptions, phToken, pMprNotifyInfo, pProfile); HookedLoggedOutSAS::Enabled(false); return msresult; }
int sis1100_ddma_map(struct sis1100_softc *sc, struct sis1100_fdata* fd, struct sis1100_ddma_map* map) { struct demand_dma* dma; int i; /* we are called from 'release' with map==0 */ if ((map!=0) && (map->num!=0) && (map->size!=0)) { /*if (map->num<2) return EINVAL;*/ if (map->size&(NBPG-1)) { pINFO(sc, "ddma_map: size not multiple of page size"); return EINVAL; } if ((unsigned long)map->addr&(NBPG-1)) { pINFO(sc, "ddma_map: addr not at page boundary"); return EINVAL; } } dma=&sc->demand_dma; mutex_lock(&dma->mux); /* is an other process using DMA? */ if ((dma->status!=dma_invalid) && (dma->owner!=fd)){ mutex_unlock(&dma->mux); return EPERM; } /* is DMA still active? */ if (dma->status==dma_running) { mutex_unlock(&dma->mux); return EALREADY; } /* if DMA is initialized we will free all structures first */ if (dma->status==dma_ready) { for (i=0; i<dma->numblocks; i++) sis1100_ddma_unmap_block(sc, dma->block+i); KFREE(dma->block); dma->block=0; dma->status=dma_invalid; } /* if the user did not request a new mapping we are done here */ if ((map==0) || (map->num==0) || (map->size==0)) { mutex_unlock(&dma->mux); return 0; } pINFO(sc, "dma_map: size=%lld addr=%p num=%d", (unsigned long long)map->size, map->addr, map->num); dma->block=KMALLOC(map->num*sizeof(struct demand_dma_block)); if (dma->block==0) { mutex_unlock(&dma->mux); return ENOMEM; } dma->owner=fd; dma->size=map->size; dma->numblocks=map->num; dma->uaddr=map->addr; for (i=0; i<dma->numblocks; i++) sis1100_ddma_zero(dma->block+i); for (i=0; i<dma->numblocks; i++) { struct demand_dma_block* block=dma->block+i; int res; block->uaddr=dma->uaddr+i*dma->size; block->size=dma->size; #ifdef __NetBSD__ block->p=fd->p; #endif /*pINFO(sc, "dma_map: try block %d", i);*/ res=sis1100_ddma_map_block(sc, block); if (res) { int j; pINFO(sc, "dma_map: block %d: res=%d", i, res); for (j=0; j<dma->numblocks; j++) sis1100_ddma_unmap_block(sc, dma->block+j); KFREE(dma->block); dma->block=0; mutex_unlock(&dma->mux); return res; } } for (i=0; i<dma->numblocks; i++) { pERROR(sc, "dmadpr0[%d]=%08x", i, dma->block[i].dmadpr0); } dma->status=dma_ready; mutex_unlock(&dma->mux); return 0; }