/*********************************************************************** * ICClose [MSVFW32.@] */ LRESULT WINAPI ICClose(HIC hic) { WINE_HIC* whic = MSVIDEO_GetHicPtr(hic); WINE_HIC** p; TRACE("(%p)\n",hic); if (!whic) return ICERR_BADHANDLE; if (whic->driverproc) { MSVIDEO_SendMessage(whic, DRV_CLOSE, 0, 0); MSVIDEO_SendMessage(whic, DRV_DISABLE, 0, 0); MSVIDEO_SendMessage(whic, DRV_FREE, 0, 0); } else { CloseDriver(whic->hdrv, 0, 0); } /* remove whic from list */ for (p = &MSVIDEO_FirstHic; *p != NULL; p = &((*p)->next)) { if ((*p) == whic) { *p = whic->next; break; } } HeapFree(GetProcessHeap(), 0, whic); return 0; }
/*********************************************************************** * ICSendMessage [MSVFW32.@] */ LRESULT VFWAPI ICSendMessage(HIC hic, UINT msg, DWORD_PTR lParam1, DWORD_PTR lParam2) { WINE_HIC* whic = MSVIDEO_GetHicPtr(hic); if (!whic) return ICERR_BADHANDLE; return MSVIDEO_SendMessage(whic, msg, lParam1, lParam2); }
/****************************************************************** * IC_Callback3216 * * */ static LRESULT CALLBACK IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD lp1, DWORD lp2) { WINE_HIC* whic; WORD args[8]; whic = MSVIDEO_GetHicPtr(hic); if (whic) { DWORD ret = 0; switch (msg) { case DRV_OPEN: lp2 = (DWORD)MapLS((void*)lp2); break; } args[7] = HIWORD(hic); args[6] = LOWORD(hic); args[5] = HDRVR_16(whic->hdrv); args[4] = msg; args[3] = HIWORD(lp1); args[2] = LOWORD(lp1); args[1] = HIWORD(lp2); args[0] = LOWORD(lp2); WOWCallback16Ex( whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &ret ); switch (msg) { case DRV_OPEN: UnMapLS(lp2); break; } return ret; } else return ICERR_BADHANDLE; }
/*********************************************************************** * ICGetInfo [MSVFW32.@] */ LRESULT VFWAPI ICGetInfo(HIC hic, ICINFO *picinfo, DWORD cb) { LRESULT ret; WINE_HIC* whic = MSVIDEO_GetHicPtr(hic); TRACE("(%p,%p,%d)\n", hic, picinfo, cb); if (!whic) return ICERR_BADHANDLE; if (!picinfo) return MMSYSERR_INVALPARAM; /* (WS) The field szDriver should be initialized because the driver * is not obliged and often will not do it. Some applications, like * VirtualDub, rely on this field and will occasionally crash if it * goes uninitialized. */ if (cb >= sizeof(ICINFO)) picinfo->szDriver[0] = '\0'; ret = ICSendMessage(hic, ICM_GETINFO, (DWORD_PTR)picinfo, cb); /* (WS) When szDriver was not supplied by the driver itself, apparently * Windows will set its value equal to the driver file name. This can * be obtained from the registry as we do here. */ if (cb >= sizeof(ICINFO) && picinfo->szDriver[0] == 0) { ICINFO ii; memset(&ii, 0, sizeof(ii)); ii.dwSize = sizeof(ii); ICInfo(picinfo->fccType, picinfo->fccHandler, &ii); lstrcpyW(picinfo->szDriver, ii.szDriver); } return ret; }
/*********************************************************************** * ICOpenFunction [MSVFW32.@] */ HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, DRIVERPROC lpfnHandler) { ICOPEN icopen; WINE_HIC* whic; TRACE("(%s,%s,%d,%p)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode, lpfnHandler); icopen.dwSize = sizeof(ICOPEN); icopen.fccType = fccType; icopen.fccHandler = fccHandler; icopen.dwVersion = ICVERSION; icopen.dwFlags = wMode; icopen.dwError = 0; icopen.pV1Reserved = NULL; icopen.pV2Reserved = NULL; icopen.dnDevNode = 0; /* FIXME */ whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC)); if (!whic) return 0; whic->driverproc = lpfnHandler; while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++; whic->hic = (HIC)(ULONG_PTR)IC_HandleRef++; whic->next = MSVIDEO_FirstHic; MSVIDEO_FirstHic = whic; /* Now try opening/loading the driver. Taken from DRIVER_AddToList */ /* What if the function is used more than once? */ if (MSVIDEO_SendMessage(whic, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) { WARN("DRV_LOAD failed for hic %p\n", whic->hic); MSVIDEO_FirstHic = whic->next; HeapFree(GetProcessHeap(), 0, whic); return 0; } /* return value is not checked */ MSVIDEO_SendMessage(whic, DRV_ENABLE, 0L, 0L); whic->driverId = (DWORD)MSVIDEO_SendMessage(whic, DRV_OPEN, 0, (DWORD_PTR)&icopen); /* FIXME: What should we put here? */ whic->hdrv = NULL; if (whic->driverId == 0) { WARN("DRV_OPEN failed for hic %p\n", whic->hic); MSVIDEO_FirstHic = whic->next; HeapFree(GetProcessHeap(), 0, whic); return 0; } TRACE("=> %p\n", whic->hic); return whic->hic; }
/*********************************************************************** * ICSendMessage [MSVIDEO.205] */ LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) { LRESULT ret = ICERR_BADHANDLE; WINE_HIC* whic; whic = MSVIDEO_GetHicPtr(HIC_32(hic)); if (whic) { /* we've got a 16 bit driver proc... call it directly */ if (whic->driverproc16) { WORD args[8]; DWORD result; /* FIXME: original code was passing hdrv first and hic second */ /* but this doesn't match what IC_Callback3216 does */ args[7] = HIWORD(hic); args[6] = LOWORD(hic); args[5] = HDRVR_16(whic->hdrv); args[4] = msg; args[3] = HIWORD(lParam1); args[2] = LOWORD(lParam1); args[1] = HIWORD(lParam2); args[0] = LOWORD(lParam2); WOWCallback16Ex( whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &result ); ret = result; } else { /* map the message for a 32 bit infrastructure, and pass it along */ void* data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2); ret = MSVIDEO_SendMessage(whic, msg, lParam1, lParam2); if (data16) MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2); } } return ret; }
/*********************************************************************** * ICOpen [MSVFW32.@] * Opens an installable compressor. Return special handle. */ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) { WCHAR codecname[10]; ICOPEN icopen; HDRVR hdrv; WINE_HIC* whic; static const WCHAR drv32W[] = {'d','r','i','v','e','r','s','3','2','\0'}; reg_driver* driver; TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode); /* Check if there is a registered driver that matches */ driver = reg_driver_list; while(driver) if (!compare_fourcc(fccType, driver->fccType) && !compare_fourcc(fccHandler, driver->fccHandler)) break; else driver = driver->next; if (driver && driver->proc) /* The driver has been registered at runtime with its driverproc */ return ICOpenFunction(fccType, fccHandler, wMode, driver->proc); /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the * same layout as ICOPEN */ icopen.dwSize = sizeof(ICOPEN); icopen.fccType = fccType; icopen.fccHandler = fccHandler; icopen.dwVersion = 0x00001000; /* FIXME */ icopen.dwFlags = wMode; icopen.dwError = 0; icopen.pV1Reserved = NULL; icopen.pV2Reserved = NULL; icopen.dnDevNode = 0; /* FIXME */ if (!driver) { /* The driver is registered in the registry */ fourcc_to_string(codecname, fccType); codecname[4] = '.'; fourcc_to_string(codecname + 5, fccHandler); codecname[9] = '\0'; hdrv = OpenDriver(codecname, drv32W, (LPARAM)&icopen); if (!hdrv) return 0; } else { /* The driver has been registered at runtime with its name */ hdrv = OpenDriver(driver->name, NULL, (LPARAM)&icopen); if (!hdrv) return 0; } whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC)); if (!whic) { CloseDriver(hdrv, 0, 0); return FALSE; } whic->hdrv = hdrv; whic->driverproc = NULL; whic->type = fccType; whic->handler = fccHandler; while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++; whic->hic = (HIC)(ULONG_PTR)IC_HandleRef++; whic->next = MSVIDEO_FirstHic; MSVIDEO_FirstHic = whic; TRACE("=> %p\n", whic->hic); return whic->hic; }
/*********************************************************************** * ICOpen [MSVFW32.@] * Opens an installable compressor. Return special handle. */ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) { WCHAR codecname[10]; ICOPEN icopen; HDRVR hdrv; WINE_HIC* whic; static const WCHAR drv32W[] = {'d','r','i','v','e','r','s','3','2','\0'}; reg_driver* driver; TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode); if (!fccHandler) /* No specific handler, return the first valid for wMode */ { HIC local; ICINFO info; DWORD loop = 0; info.dwSize = sizeof(info); while(ICInfo(fccType, loop++, &info)) { /* Ensure fccHandler is not 0x0 because we will recurse on ICOpen */ if(!info.fccHandler) continue; local = ICOpen(fccType, info.fccHandler, wMode); if (local != 0) { TRACE("Returning %s as default handler for %s\n", wine_dbgstr_fcc(info.fccHandler), wine_dbgstr_fcc(fccType)); return local; } } } /* Check if there is a registered driver that matches */ driver = reg_driver_list; while(driver) if (!compare_fourcc(fccType, driver->fccType) && !compare_fourcc(fccHandler, driver->fccHandler)) { fccType = driver->fccType; fccHandler = driver->fccHandler; break; } else driver = driver->next; if (driver && driver->proc) /* The driver has been registered at runtime with its driverproc */ return ICOpenFunction(fccType, fccHandler, wMode, driver->proc); /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the * same layout as ICOPEN */ icopen.dwSize = sizeof(ICOPEN); icopen.fccType = fccType; icopen.fccHandler = fccHandler; icopen.dwVersion = 0x00001000; /* FIXME */ icopen.dwFlags = wMode; icopen.dwError = 0; icopen.pV1Reserved = NULL; icopen.pV2Reserved = NULL; icopen.dnDevNode = 0; /* FIXME */ if (!driver) { /* normalize to lower case as in 'vidc' */ ((char*)&fccType)[0] = tolower(((char*)&fccType)[0]); ((char*)&fccType)[1] = tolower(((char*)&fccType)[1]); ((char*)&fccType)[2] = tolower(((char*)&fccType)[2]); ((char*)&fccType)[3] = tolower(((char*)&fccType)[3]); icopen.fccType = fccType; /* Seek the driver in the registry */ fourcc_to_string(codecname, fccType); codecname[4] = '.'; fourcc_to_string(codecname + 5, fccHandler); codecname[9] = '\0'; hdrv = OpenDriver(codecname, drv32W, (LPARAM)&icopen); if (!hdrv) return 0; } else { /* The driver has been registered at runtime with its name */ hdrv = OpenDriver(driver->name, NULL, (LPARAM)&icopen); if (!hdrv) return 0; } whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC)); if (!whic) { CloseDriver(hdrv, 0, 0); return FALSE; } whic->hdrv = hdrv; whic->driverproc = NULL; whic->type = fccType; whic->handler = fccHandler; while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++; whic->hic = (HIC)(ULONG_PTR)IC_HandleRef++; whic->next = MSVIDEO_FirstHic; MSVIDEO_FirstHic = whic; TRACE("=> %p\n", whic->hic); return whic->hic; }