/************************************************************************* * AssocQueryStringA [SHLWAPI.@] * * Get a file association string from the registry. * * PARAMS * cfFlags [I] ASSOCF_ flags from "shlwapi.h" * str [I] Type of string to get (ASSOCSTR enum from "shlwapi.h") * pszAssoc [I] Key name to search below * pszExtra [I] Extra information about the string location * pszOut [O] Destination for the association string * pcchOut [O] Length of pszOut * * RETURNS * Success: S_OK. pszOut contains the string, pcchOut contains its length. * Failure: An HRESULT error code indicating the error. */ HRESULT WINAPI AssocQueryStringA(ASSOCF cfFlags, ASSOCSTR str, LPCSTR pszAssoc, LPCSTR pszExtra, LPSTR pszOut, DWORD *pcchOut) { WCHAR szAssocW[MAX_PATH], *lpszAssocW = NULL; WCHAR szExtraW[MAX_PATH], *lpszExtraW = NULL; HRESULT hRet = E_OUTOFMEMORY; TRACE("(0x%8x,0x%8x,%s,%s,%p,%p)\n", cfFlags, str, debugstr_a(pszAssoc), debugstr_a(pszExtra), pszOut, pcchOut); if (!pcchOut) hRet = E_UNEXPECTED; else if (SHLWAPI_ParamAToW(pszAssoc, szAssocW, MAX_PATH, &lpszAssocW) && SHLWAPI_ParamAToW(pszExtra, szExtraW, MAX_PATH, &lpszExtraW)) { WCHAR szReturnW[MAX_PATH], *lpszReturnW = szReturnW; DWORD dwLenOut = *pcchOut; if (dwLenOut >= MAX_PATH) lpszReturnW = HeapAlloc(GetProcessHeap(), 0, (dwLenOut + 1) * sizeof(WCHAR)); else dwLenOut = sizeof(szReturnW) / sizeof(szReturnW[0]); if (!lpszReturnW) hRet = E_OUTOFMEMORY; else { hRet = AssocQueryStringW(cfFlags, str, lpszAssocW, lpszExtraW, lpszReturnW, &dwLenOut); if (SUCCEEDED(hRet)) dwLenOut = WideCharToMultiByte(CP_ACP, 0, lpszReturnW, -1, pszOut, *pcchOut, NULL, NULL); *pcchOut = dwLenOut; if (lpszReturnW != szReturnW) HeapFree(GetProcessHeap(), 0, lpszReturnW); } } if (lpszAssocW != szAssocW) HeapFree(GetProcessHeap(), 0, lpszAssocW); if (lpszExtraW != szExtraW) HeapFree(GetProcessHeap(), 0, lpszExtraW); return hRet; }
/*--------------------------------------------------------------------------*/ char *FindFileAssociation (char *ptrFindStr,char *Extra) { char *ptrResult = NULL ; if ( ptrFindStr ) { wchar_t *wcptrFindStr = to_wide_string(ptrFindStr); wchar_t *wcExtra = to_wide_string(Extra); wchar_t szDefault[PATH_MAX + FILENAME_MAX]; DWORD ccDefault = PATH_MAX + FILENAME_MAX; if (wcptrFindStr) { HRESULT rc = AssocQueryStringW (0, ASSOCSTR_EXECUTABLE,wcptrFindStr, wcExtra, szDefault, &ccDefault); if (ccDefault) { if (rc == S_OK) ptrResult = wide_string_to_UTF8(szDefault); } } } return ptrResult; }
/////////////////////////////////////////////////////////////////////////////// // // _AssocQueryString() - private function // // Purpose: Calls AssocQueryStringW() to get associated application. // // Parameters: See AssocQueryString() in MSDN. // // Returns: HRESULT - S_OK = AssocQueryStringW() succeeded // // Notes: This code is necessary because AssocQueryStringA() doesn't // work (confirmed by MS Tech Support), so for ANSI version // we convert parameters to Unicode and call wide version. // static HRESULT _AssocQueryString(ASSOCF flags, ASSOCSTR str, LPCTSTR pszAssoc, LPCTSTR pszExtra, // may be NULL LPTSTR pszOut, DWORD *pcchOut) // size of pszOut in TCHARs { HRESULT hr = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND); if (!pszOut || !pcchOut || (*pcchOut == 0) || !pszAssoc || (pszAssoc[0] == _T('\0'))) { TRACE(_T("ERROR: _AssocQueryString: bad parameters\n")); return hr; } *pszOut = 0; #ifdef _UNICODE hr = AssocQueryStringW(flags, str, pszAssoc, pszExtra, pszOut, pcchOut); #else // get size of buffer for pszAssoc int wlen = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszAssoc, -1, NULL, 0); TRACE(_T("wlen=%d\n"), wlen); WCHAR *pszAssocW = new WCHAR [wlen+16]; pszAssocW[0] = 0; // convert pszAssoc to unicode MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszAssoc, -1, pszAssocW, wlen+2); // get size of buffer for pszExtra WCHAR *pszExtraW = NULL; if (pszExtra && (pszExtra[0] != _T('\0'))) { wlen = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszExtra, -1, NULL, 0); TRACE(_T("wlen=%d\n"), wlen); pszExtraW = new WCHAR [wlen+16]; pszExtraW[0] = 0; // convert pszExtra to unicode MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszExtra, -1, pszExtraW, wlen+2); } // create buffer for wide-character output WCHAR *pszOutW = new WCHAR [MAX_PATH*3]; pszOutW[0] = 0; DWORD dwOut = MAX_PATH*3 - 4; // get exe filepath hr = AssocQueryStringW(flags, str, pszAssocW, pszExtraW, pszOutW, &dwOut); // convert exe filepath to ansi WideCharToMultiByte(CP_ACP, 0, pszOutW, -1, pszOut, *pcchOut, NULL, NULL); *pcchOut = _tcslen(pszOut); delete [] pszAssocW; delete [] pszExtraW; delete [] pszOutW; #endif return hr; }
/* ** Open file using file association if necessary. This can be necessary if ** the file is being used by another process. */ int willusgui_open_file_ex(char *filename) { char ext[512]; short *extw; short exew[512]; char *exename; char pwd[512]; char cmdargs[512]; int maxsize,status,procnum; HRESULT hr; static char *funcname="willusgui_open_file_ex"; status=willusgui_open_file(filename); if (status!=-1) return(status); strncpy(&ext[1],wfile_ext(filename),510); ext[511]='\0'; ext[0]='.'; utf8_to_utf16_alloc((void **)&extw,ext); maxsize=511; hr=AssocQueryStringW(0,ASSOCSTR_EXECUTABLE,(LPCWSTR)extw,NULL,(LPWSTR)exew,(DWORD *)&maxsize); willus_mem_free((double **)&extw,funcname); if (hr==S_OK) utf16_to_utf8_alloc((void **)&exename,exew); if (hr!=S_OK || wfile_status(exename)!=1) { char *message; int len; static char *funcname="willusgui_open_file_ex"; static int bcolors[3]= {0x6060b0,0xf0f0f0,0xf0f0f0}; if (hr==S_OK) willus_mem_free((double **)&exename,funcname); len=strlen(filename); willus_mem_alloc_warn((void **)&message,len+80,funcname,10); sprintf(message,"Cannot find application to open %s!",filename); willusgui_message_box(NULL,"Error",message,"*&OK",NULL,NULL, NULL,0,24,640,0xe0e0e0,bcolors,NULL,1); willus_mem_free((double **)&message,funcname); return(0); } /* Put quotes around filename -> cmdargs */ strncpy(&cmdargs[1],filename,509); cmdargs[510]='\0'; cmdargs[0]='\"'; maxsize=strlen(cmdargs); cmdargs[maxsize]='\"'; cmdargs[maxsize+1]='\0'; /* Get working directory */ strncpy(pwd,wfile_get_wd(),511); pwd[511]='\0'; /* Make sure PWD isn't UNC -- if it is, default C:\ */ if (pwd[0]=='\\' && pwd[1]=='\\') strcpy(pwd,"C:\\"); process_launch_ex(exename,cmdargs,1,1,pwd,1,&procnum); willus_mem_free((double **)&exename,funcname); return(1); /* if (procnum>=0) { int status,exitcode; while ((status=process_done_ex(procnum,&exitcode))==0) win_sleep(10); if (exitcode==0) return(1); } */ }