⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 device.c

📁 windows ce 3.00 嵌入式操作系统源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                DEBUGMSG(1, (TEXT("WARNING (device.c): fsodev (0x%X) not in DEVICE.EXE list\r\n"), fsodev));
            }
		}
        if (lpdev = fsodev->lpDev) {
            LeaveCriticalSection(&g_devcs);
			ENTER_INSTRUM {
		    lpdev->fnClose(fsodev->dwOpenData);
			} EXIT_INSTRUM_CLOSE;
            EnterCriticalSection(&g_devcs);
    	}
        if (fsodev->dwOpenRefCnt) {
            fsodev->nextptr = g_lpDyingOpens;
            g_lpDyingOpens = fsodev;
            SetEvent(g_hCleanEvt);
        } else {
            LocalFree(fsodev);
        }
		retval = TRUE;
	} EXIT_DEVICE_FUNCTION;
	return retval;
}

void OpenAddRef(fsopendev_t *fsodev)
{
    InterlockedIncrement(&fsodev->dwOpenRefCnt);
    InterlockedIncrement(fsodev->lpdwDevRefCnt);
}

void OpenDelRef(fsopendev_t *fsodev)
{
    InterlockedDecrement(&fsodev->dwOpenRefCnt);
    InterlockedDecrement(fsodev->lpdwDevRefCnt);
}

BOOL FS_DevReadFile(fsopendev_t *fsodev, LPVOID buffer, DWORD nBytesToRead, LPDWORD lpNumBytesRead,
	LPOVERLAPPED lpOverlapped)
{
	BOOL retval = FALSE;
	DWORD dodec = 0;
	__try {
		if (!fsodev->lpDev)
			SetLastError(ERROR_GEN_FAILURE);
		else {
			OpenAddRef(fsodev);
			dodec = 1;
			ENTER_INSTRUM {
			*lpNumBytesRead = fsodev->lpDev->fnRead(fsodev->dwOpenData,buffer,nBytesToRead);
			} EXIT_INSTRUM_READ;
			OpenDelRef(fsodev);
			dodec = 0;
			if (*lpNumBytesRead == 0xffffffff) {
				retval = FALSE;
				*lpNumBytesRead = 0;
			} else
				retval = TRUE;
		}
	} __except (EXCEPTION_EXECUTE_HANDLER) {
		if (dodec)
			OpenDelRef(fsodev);
		SetLastError(ERROR_INVALID_PARAMETER);
	}
	return retval;
}

BOOL FS_DevWriteFile(fsopendev_t *fsodev, LPCVOID buffer, DWORD nBytesToWrite, LPDWORD lpNumBytesWritten,
	LPOVERLAPPED lpOverlapped)
{
	BOOL retval = FALSE;
	DWORD dodec = 0;
	__try {
		if (!fsodev->lpDev)
			SetLastError(ERROR_GEN_FAILURE);
		else {
			OpenAddRef(fsodev);
			dodec = 1;
			ENTER_INSTRUM {
			*lpNumBytesWritten = fsodev->lpDev->fnWrite(fsodev->dwOpenData,buffer,nBytesToWrite);
			} EXIT_INSTRUM_WRITE;
			OpenDelRef(fsodev);
			dodec = 0;
			if (*lpNumBytesWritten == 0xffffffff)
				*lpNumBytesWritten = 0;
			else
				retval = TRUE;
		}
	} __except (EXCEPTION_EXECUTE_HANDLER) {
		if (dodec)
			OpenDelRef(fsodev);
		SetLastError(ERROR_INVALID_PARAMETER);
	}
	return retval;
}

DWORD FS_DevSetFilePointer(fsopendev_t *fsodev, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh,
	DWORD dwMoveMethod) {
	DWORD retval = 0xffffffff;
	DWORD dodec = 0;
	__try {
		if (!fsodev->lpDev)
			SetLastError(ERROR_GEN_FAILURE);
		else {
			OpenAddRef(fsodev);
			dodec = 1;
			ENTER_INSTRUM {
			retval = fsodev->lpDev->fnSeek(fsodev->dwOpenData,lDistanceToMove,dwMoveMethod);
			} EXIT_INSTRUM_SEEK;
			OpenDelRef(fsodev);
			dodec = 0;
		}
	} __except (EXCEPTION_EXECUTE_HANDLER) {
		if (dodec)
			OpenDelRef(fsodev);
		SetLastError(ERROR_INVALID_PARAMETER);
	}
	return retval;
}

BOOL FS_DevDeviceIoControl(fsopendev_t *fsodev, DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
    BOOL retval = FALSE;
    DWORD dodec = 0;
    __try {
        if (!fsodev->lpDev)
            SetLastError(ERROR_GEN_FAILURE);
        else {
            if(dwIoControlCode == IOCTL_DEVICE_AUTODEREGISTER) {
                // NOTE: This IOCTL is here to avoid a deadlock between (a) a DllMain calling
                // DeregisterDevice (and hence trying to acquire the device CS *after* the 
                // loader CS and (b) Various other paths in this file where we acquire the 
                // device CS *before* the Loader CS (by calling LoadLib, FreeLib etc). 
                // See WinCE#4165. Hence this code path must NOT acquire the device CS!!
                DEBUGMSG(ZONE_DYING, (L"FS_DevDeviceIoControl:IOCTL_DEVICE_AUTODEREGISTER. lpdev=%x\r\n", fsodev->lpDev));
                fsodev->lpDev->wFlags |= DEVFLAGS_AUTO_DEREGISTER;
                retval = TRUE;
                // signal the main device (dying-devs-handler) thread
                SetEvent(g_hCleanEvt);
            }
            else {
                OpenAddRef(fsodev);
                dodec = 1;
                ENTER_INSTRUM {
                    retval = fsodev->lpDev->fnControl(fsodev->dwOpenData,dwIoControlCode,lpInBuf,nInBufSize,lpOutBuf,nOutBufSize,lpBytesReturned);
                } EXIT_INSTRUM_IOCONTROL;
                OpenDelRef(fsodev);
                dodec = 0;
            }
        }
    } __except (EXCEPTION_EXECUTE_HANDLER) {
        if (dodec)
			OpenDelRef(fsodev);
        SetLastError(ERROR_INVALID_PARAMETER);
    }
    return retval;
}

DWORD FS_DevGetFileSize(fsopendev_t *fsodev, LPDWORD lpFileSizeHigh) {
	SetLastError(ERROR_INVALID_FUNCTION);
	return 0xffffffff;
}

BOOL FS_DevGetFileInformationByHandle(fsopendev_t *fsodev, LPBY_HANDLE_FILE_INFORMATION lpFileInfo) {
	SetLastError(ERROR_INVALID_FUNCTION);
	return FALSE;
}

BOOL FS_DevFlushFileBuffers(fsopendev_t *fsodev) {
	SetLastError(ERROR_INVALID_FUNCTION);
	return FALSE;
}

BOOL FS_DevGetFileTime(fsopendev_t *fsodev, LPFILETIME lpCreation, LPFILETIME lpLastAccess, LPFILETIME lpLastWrite) {
	SetLastError(ERROR_INVALID_FUNCTION);
	return FALSE;
}

BOOL FS_DevSetFileTime(fsopendev_t *fsodev, CONST FILETIME *lpCreation, CONST FILETIME *lpLastAccess, CONST FILETIME *lpLastWrite) {
	SetLastError(ERROR_INVALID_FUNCTION);
	return FALSE;
}

BOOL FS_DevSetEndOfFile(fsopendev_t *fsodev) {
	SetLastError(ERROR_INVALID_FUNCTION);
	return FALSE;
}

static void DevPSLNotify (DWORD flags, HPROCESS proc, HTHREAD thread) {
	fsopendev_t *fsodev;
	int			icalls, i;
	HANDLE		h[20];
	HANDLE		*ph;

	DEVICE_PSL_NOTIFY	pslPacket;

	EnterCriticalSection(&g_devcs);

	fsodev = g_lpOpenDevs;

	icalls = 0;

	while (fsodev) {
		if (fsodev->hProc == proc)
			++icalls;
		fsodev = fsodev->nextptr;
	}

	if (icalls < sizeof(h) / sizeof(h[0]))
		ph = h;
	else
		ph = (HANDLE *)LocalAlloc (LMEM_FIXED, icalls * sizeof(HANDLE));

	i = 0;
	fsodev = g_lpOpenDevs;

	while (fsodev && i < icalls) {
		if (fsodev->hProc == proc)
			ph[i++] = fsodev->KHandle;
		fsodev = fsodev->nextptr;
	}

	LeaveCriticalSection (&g_devcs);

	pslPacket.dwSize  = sizeof(pslPacket);
	pslPacket.dwFlags = flags;
	pslPacket.hProc   = proc;
	pslPacket.hThread = thread;

	for (i = 0 ; i < icalls ; ++i)
		DeviceIoControl (ph[i], IOCTL_PSL_NOTIFY, (LPVOID)&pslPacket, sizeof(pslPacket), NULL, 0, NULL, NULL);

	if (ph != h)
		LocalFree (ph);
}

void FS_DevProcNotify(DWORD flags, HPROCESS proc, HTHREAD thread) {
	switch (flags) {
#ifndef TARGET_NT
		case DLL_PROCESS_EXITING:
			DevPSLNotify (flags, proc, thread);
			break;
		case DLL_SYSTEM_STARTED:
			//
			// Eventually we'll want to signal all drivers that the system has
			// initialized.  For now do what's necessary.
			// 
			DevloadPostInit();
			break;
#endif // TARGET_NT
	}

	return;
}

void FS_CloseAllDeviceHandles(HPROCESS proc) {
#if TARGET_NT
	ENTER_DEVICE_FUNCTION {
#endif
	fsopendev_t *fsodev = g_lpOpenDevs;
	while (fsodev) {
		if (fsodev->hProc == proc) {
#if TARGET_NT
			FS_DevCloseFileHandle(fsodev);
#else
			CloseHandle(fsodev->KHandle);
#endif
			fsodev = g_lpOpenDevs;
		} else
			fsodev = fsodev->nextptr;
	}
#if TARGET_NT
	} EXIT_DEVICE_FUNCTION;
#endif
}

#ifndef TARGET_NT
void InitOOMSettings()
{
	SYSTEM_INFO	SysInfo;
	GetSystemInfo (&SysInfo);

	// Calling this will set up the initial critical memory handlers and
	// enable memory scavenging in the kernel
	SetOOMEvent (NULL, 30, 15, 0x4000 / SysInfo.dwPageSize,
				 (0x2000 / SysInfo.dwPageSize) > 2 ?
				 (0x2000 / SysInfo.dwPageSize) : 2);	
}


void ProcessDyingOpens(void)
{
	fsopendev_t *fsodev;
	fsopendev_t *fsodevprev;

    DEBUGMSG(ZONE_DYING, (L"Device: About to walk dying opens list\r\n"));
    EnterCriticalSection(&g_devcs);
    fsodevprev = fsodev = g_lpDyingOpens;
    while (fsodev) {
        if (fsodev->dwOpenRefCnt == 0) {
            // Unlink and free unreferenced open
            if (fsodev == g_lpDyingOpens) {
                g_lpDyingOpens = fsodev->nextptr;
                LocalFree(fsodev);
                fsodev = fsodevprev = g_lpDyingOpens;
            } else {
                fsodevprev->nextptr = fsodev->nextptr;
                LocalFree(fsodev);
                fsodev = fsodevprev->nextptr;
            }
        } else {
            fsodevprev = fsodev;
            fsodev = fsodev->nextptr;
        }
    }
    LeaveCriticalSection(&g_devcs);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR lpCmdLine, int nCmShow)
{
    fsdev_t* lpdev;
    BOOL bFreedOne;
	if (IsAPIReady(SH_DEVMGR_APIS))
		return 0;

	InitOOMSettings();
	
    InitializeListHead(&g_DevChain);
    InitializeListHead(&g_DyingDevs);
    g_hCleanEvt = CreateEvent(0,0,0,0);
    g_hCleanDoneEvt = CreateEvent(0, 1, 1, 0); //manual reset, init state signalled
    g_hDevApiHandle = CreateAPISet("WFLD", NUM_FDEV_APIS, FDevApiMethods, FDevApiSigs);
    RegisterAPISet(g_hDevApiHandle, SH_DEVMGR_APIS);
    g_hDevFileApiHandle = CreateAPISet("W32D", NUM_FAPIS, DevFileApiMethods, DevFileApiSigs);
    RegisterAPISet(g_hDevFileApiHandle, HT_FILE | REGISTER_APISET_TYPE);
    InitializeCriticalSection(&g_devcs);
    SetPowerOffHandler((FARPROC)FS_PowerAllDevices);
    DevloadInit();
    SignalStarted(_wtol(lpCmdLine));
    while (1) {
        WaitForSingleObject(g_hCleanEvt, INFINITE);

        // check for auto-deregister devs first as they may end up queuing 
        // themselves on the dying devs list
        do {
            EnterCriticalSection(&g_devcs);
            bFreedOne = FALSE;
            // walking the chain of *active* devs, looking for ALL that want to deregister
            // don't care about refcount. That's handled by deregister & the dying-devs list
            DEBUGMSG(ZONE_DYING, (L"Device: About to walk main list\r\n"));
            for (lpdev = (fsdev_t *)g_DevChain.Flink;
                 lpdev != (fsdev_t *)&g_DevChain;
                 lpdev = (fsdev_t *)(lpdev->list.Flink)) {
                if (lpdev->wFlags & DEVFLAGS_AUTO_DEREGISTER) {
                    LeaveCriticalSection(&g_devcs);
                    // don't remove from list. DeregisterDevice will do that
                    DEBUGMSG(ZONE_DYING, (L"Device: FOUND auto-deregister lpdev=%x\r\n", lpdev));
                    FS_DeregisterDevice((HANDLE)lpdev);
                    bFreedOne = TRUE;
                    break;
                    // break out of inner loop, because after letting go of critsec &
                    // freeing lpdev, our loop traversal is not valid anymore. So start over
                }
            }
            if (lpdev == (fsdev_t *)&g_DevChain) {
                LeaveCriticalSection(&g_devcs);
                break;
            }
        } while (bFreedOne);
        // keep looping as long as we have something to do
        
        DEBUGMSG(ZONE_DYING, (L"Device: About to walk dying list\r\n"));
        while (!IsListEmpty(&g_DyingDevs)) 
        {
            EnterCriticalSection(&g_devcs);
            bFreedOne = FALSE;
            // walk the chain of dying devs (already deregistered. just waiting to be unloaded)
            for (lpdev = (fsdev_t *)g_DyingDevs.Flink;
                 lpdev != (fsdev_t *)&g_DyingDevs;
                 lpdev = (fsdev_t *)lpdev->list.Flink) {
                if (!lpdev->dwRefCnt) {
                    RemoveEntryList((PLIST_ENTRY)lpdev);
                    LeaveCriticalSection(&g_devcs);
                    DEBUGMSG(ZONE_DYING, (L"Device: FOUND dying dev lpdev=%x\r\n", lpdev));
                    DoFreeDevice(lpdev);
                    bFreedOne = TRUE;
                    break; 
                    // break out of inner loop, because after letting go of critsec &
                    // freeing lpdev, our loop traversal is not valid anymore. So start over
                }
            }
            if (bFreedOne == FALSE) {
                // Couldn't free anyone
                LeaveCriticalSection(&g_devcs);
                Sleep(5000);    // snooze, and try again...
            }
        }

        ProcessDyingOpens();

	    DEBUGMSG(ZONE_DYING, (TEXT("DEVICE: Setting CleanDoneEvt in WinMain.\r\n")));

        SetEvent(g_hCleanDoneEvt);
    }
    return 1;    // should not ever be reached
}
#else 

BOOL
WINAPI
SetPriorityClass(
    HANDLE hProcess,
    DWORD dwPriorityClass
    );

int wmain(int argc, wchar_t *argv)
{
	SetPriorityClass(GetCurrentProcess(), 0x80 /*HIGH_PRIORITY_CLASS*/);
	InitializeCriticalSection(&g_devcs);
	g_hDevFileApiHandle = (HANDLE) 0x80002000;
	if (!proxy_init(8, 4096))
		return 0;
	DevloadInit();
	DevloadPostInit();
	wait_for_exit_event(); 
	return 1;
}
#endif // TARGET_NT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -