<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
<module name="iexplore" type="win32gui" installbase="system32" installname="iexplore.exe" unicode="no">
<include base="iexplore">.</include>
- <library>kernel32</library>
<library>user32</library>
<library>gdi32</library>
- <library>shdocvw</library>
+ <library>shdocvw</library>
<file>main.c</file>
<file>version.rc</file>
</module>
}
// get computers list
- Count = SetupGetLineCount(hTxtsetupSif, _T("Computer"));
- if (Count > 0)
- {
- SetupData.pComputers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GENENTRY) * Count);
- if (SetupData.pComputers != NULL)
- {
- SetupData.CompCount = Count;
- Count = 0;
- if (SetupFindFirstLine(hTxtsetupSif, _T("Computer"), NULL, &InfContext))
- {
- do
- {
- SetupGetStringField(&InfContext,
- 0,
- SetupData.pComputers[Count].Id,
- sizeof(SetupData.pComputers[Count].Id) / sizeof(TCHAR),
- &LineLength);
-
- SetupGetStringField(&InfContext,
- 1,
- SetupData.pComputers[Count].Value,
- sizeof(SetupData.pComputers[Count].Value) / sizeof(TCHAR),
- &LineLength);
- ++Count;
- }
- while (SetupFindNextLine(&InfContext, &InfContext) && Count < SetupData.CompCount);
- }
- }
- }
+ SetupData.CompCount = LoadGenentry(hTxtsetupSif,_T("Computer"),SetupData.pComputers,&InfContext);
// get display list
- Count = SetupGetLineCount(hTxtsetupSif, _T("Display"));
- if (Count > 0)
- {
- SetupData.pDisplays = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GENENTRY) * Count);
- if (SetupData.pDisplays != NULL)
- {
- SetupData.DispCount = Count;
- Count = 0;
+ SetupData.DispCount = LoadGenentry(hTxtsetupSif,_T("Display"),SetupData.pDisplays,&InfContext);
- if (SetupFindFirstLine(hTxtsetupSif, _T("Display"), NULL, &InfContext))
- {
- do
- {
- SetupGetStringField(&InfContext,
- 0,
- SetupData.pDisplays[Count].Id,
- sizeof(SetupData.pDisplays[Count].Id) / sizeof(TCHAR),
- &LineLength);
+ // get keyboard list
+ SetupData.KeybCount = LoadGenentry(hTxtsetupSif, _T("Keyboard"),SetupData.pKeyboards,&InfContext);
- {
- SetupGetStringField(&InfContext,
- 1,
+ // get install directory
+ if (SetupFindFirstLine(hTxtsetupSif, _T("SetupData"), _T("DefaultPath"), &InfContext))
- SetupData.pDisplays[Count].Value,
- sizeof(SetupData.pDisplays[Count].Value) / sizeof(TCHAR),
++ {
+ SetupGetStringField(&InfContext,
+ 1,
- &LineLength);
- }
+ SetupData.InstallDir,
+ sizeof(SetupData.InstallDir) / sizeof(TCHAR),
- ++Count;
+ &LineLength);
- while (SetupFindNextLine(&InfContext, &InfContext) && Count < SetupData.DispCount);
+ }
- }
-}
+ SetupCloseInfFile(hTxtsetupSif);
- }
+ }
+ }
- // get keyboard list
- Count = SetupGetLineCount(hTxtsetupSif, _T("Keyboard"));
- if (Count > 0)
+ LONG LoadGenentry(HINF hinf,PCTSTR name,PGENENTRY gen,PINFCONTEXT context)
-{
+ {
- SetupData.pKeyboards = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GENENTRY) * Count);
- if (SetupData.pKeyboards != NULL)
- {
- SetupData.KeybCount = Count;
- Count = 0;
+ LONG TotalCount;
- if (SetupFindFirstLine(hTxtsetupSif, _T("Keyboard"), NULL, &InfContext))
+ TotalCount = SetupGetLineCount(hinf, name);
+ if (TotalCount > 0)
- {
+ {
+ gen = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GENENTRY) * TotalCount);
+ if (gen != NULL)
+ {
+ if (SetupFindFirstLine(hinf, name, NULL, context))
+ {
+ LONG Count = 0;
- do
- {
+ do
+ {
- SetupGetStringField(&InfContext,
+ SetupGetStringField(context,
- 0,
+ 0,
- SetupData.pKeyboards[Count].Id,
- sizeof(SetupData.pKeyboards[Count].Id) / sizeof(TCHAR),
- &LineLength);
+ gen[Count].Id,
+ sizeof(gen[Count].Id) / sizeof(TCHAR),
+ NULL);
- SetupGetStringField(&InfContext,
+ SetupGetStringField(context,
- 1,
+ 1,
- SetupData.pKeyboards[Count].Value,
- sizeof(SetupData.pKeyboards[Count].Value) / sizeof(TCHAR),
- &LineLength);
- ++Count;
+ gen[Count].Value,
+ sizeof(gen[Count].Value) / sizeof(TCHAR),
+ NULL);
+ Count++;
- }
+ }
- while (SetupFindNextLine(&InfContext, &InfContext) && Count < SetupData.KeybCount);
+ while (SetupFindNextLine(context, context) && Count < TotalCount);
+ }
}
}
- }
- // get install directory
- if (SetupFindFirstLine(hTxtsetupSif, _T("SetupData"), _T("DefaultPath"), &InfContext))
- {
- SetupGetStringField(&InfContext,
- 1,
- SetupData.InstallDir,
- sizeof(SetupData.InstallDir) / sizeof(TCHAR),
- &LineLength);
+ return TotalCount;
-}
+ }
- SetupCloseInfFile(hTxtsetupSif);
- }
- }
BOOL isUnattendSetup()
{
boot\bootdata\bootcdregtest\regtest.cmd 7 optional
; Subsystems
-subsystems\win32\csrss\csrss.exe 1
-subsystems\win32\csrss\win32csr\win32csr.dll 1
-subsystems\ntvdm\ntvdm.exe 1
-subsystems\win32\win32k\win32k.sys 1
+;subsystems\win32\csrss\csrss.exe 1
+;subsystems\win32\csrss\win32csr\win32csr.dll 1
+;subsystems\ntvdm\ntvdm.exe 1
+;subsystems\win32\win32k\win32k.sys 1
; Optional/proprietary files
- modules\optional\kvmnet.inf 6 optional
- modules\optional\kvmnet.sys 2 optional
+ modules\optional\DroidSansFallback.ttf 3 optional
+ modules\optional\NOTICE_for_Droid_Font.txt 4 optional
+ modules\optional\netkvm2k.inf 6 optional
+ modules\optional\netkvm2k.cat 6 optional
+ modules\optional\netkvm.sys 2 optional
modules\optional\alcxwdm.inf 6 optional
modules\optional\alcxwdm.sys 2 optional
modules\optional\mfc42.dll 1 optional
<define name="WIN32" />
<define name="_WINDOWS" />
<define name="_MBCS" />
++ <define name="HAVE_STAT" />
<define name="HAVE_WIN32_THREADS" />
<define name="_REENTRANT" />
<define name="_WINSOCKAPI_" />
//SetDoubleClickTime(pButtonData->g_DoubleClickSpeed);
#if (WINVER >= 0x0500)
-- SystemParametersInfo(SPI_SETMOUSECLICKLOCK, 0, (PVOID)pButtonData->g_ClickLockEnabled, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
++ SystemParametersInfo(SPI_SETMOUSECLICKLOCK, 0, UlongToPtr(pButtonData->g_ClickLockEnabled), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
if (pButtonData->g_ClickLockEnabled)
SystemParametersInfo(SPI_SETMOUSECLICKLOCKTIME, pButtonData->g_ClickLockTime, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
#endif
//#if (WINVER >= 0x0500)
if (pPointerData->bOrigCursorShadow != pPointerData->bCursorShadow)
{
-- SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)pPointerData->bCursorShadow, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
++ SystemParametersInfo(SPI_SETCURSORSHADOW, 0, UlongToPtr(pPointerData->bCursorShadow), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
pPointerData->bOrigCursorShadow = pPointerData->bCursorShadow;
}
//#endif
else if (lppsn->hdr.code == PSN_RESET)
{
//#if (WINVER >= 0x0500)
-- SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)pPointerData->bOrigCursorShadow, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
++ SystemParametersInfo(SPI_SETCURSORSHADOW, 0, UlongToPtr(pPointerData->bOrigCursorShadow), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
//#endif
}
break;
}
DriverNameA[0] = 0;
- WideCharToMultiByte(CP_ACP, 0, ProductName, -1, DriverNameA, sizeof(DriverNameA) / sizeof(char), NULL, NULL);
+ if (ProductName)
+ {
+ WideCharToMultiByte(CP_ACP, 0, ProductName, -1, DriverNameA, sizeof(DriverNameA) / sizeof(char), NULL, NULL);
+ DriverNameA[(sizeof(DriverNameA) / sizeof(char))-1] = 0;
+ }
return lpDSEnumCallbackA(DeviceGuid, (LPSTR)Buffer, DriverNameA, lpContext);
}
MAX_PATH,
DosName,
NULL) == 0)
- return STATUS_DLL_NOT_FOUND;
+ {
+ /* try to find active context dll */
+ Status = find_actctx_dll(DllName->Buffer, DosName);
+ if(Status == STATUS_SUCCESS)
+ DPRINT("found %S for %S\n", DosName,DllName->Buffer);
+ else
+ return STATUS_DLL_NOT_FOUND;
+ }
if (!RtlDosPathNameToNtPathName_U (DosName,
&FullNtFileName,
OUT PULONG Disposition OPTIONAL,
OUT PULONG Cookie OPTIONAL)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ BOOLEAN Ret;
+ BOOLEAN CookieSet = FALSE;
+
+ if ((Flags != 0x01) && (Flags != 0x02))
+ return STATUS_INVALID_PARAMETER_1;
+
+ if (!Cookie) return STATUS_INVALID_PARAMETER_3;
+
+ /* Set some defaults for failure while verifying params */
+ _SEH2_TRY
+ {
+ *Cookie = 0;
+ CookieSet = TRUE;
+ if (Disposition) *Disposition = 0;
- }
++}
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ if (CookieSet)
+ Status = STATUS_INVALID_PARAMETER_3;
+ else
+ Status = STATUS_INVALID_PARAMETER_2;
+ }
+ _SEH2_END;
+
+ if (Flags == 0x01)
+ {
+ DPRINT1("Warning: Reporting errors with exception not supported yet!\n");
+ RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
+ Status = STATUS_SUCCESS;
+
+ }
+ else
+ {
+ if (!Disposition) return STATUS_INVALID_PARAMETER_2;
+
+ Ret = RtlTryEnterCriticalSection(NtCurrentPeb()->LoaderLock);
+
+ if (Ret)
+ *Disposition = 0x01;
+ else
+ *Disposition = 0x02;
+
+ Status = STATUS_SUCCESS;
+ }
+
+ /* FIXME: Cookie is based on part of the thread id */
+ *Cookie = (ULONG)NtCurrentTeb()->RealClientId.UniqueThread;
+ return Status;
}
NTSTATUS
else
{
ret = TRUE;
- if ( TranslatedName )
+
+ dwAccountName = TranslatedName->Name.Length / sizeof(WCHAR);
+ if (ReferencedDomain && ReferencedDomain->Entries > 0)
+ dwDomainName = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR);
+ else
+ dwDomainName = 0;
+
+ if (*pdwAccountName <= dwAccountName || *pdwDomainName <= dwDomainName)
{
- DWORD dwSrcLen = TranslatedName->Name.Length / sizeof(WCHAR);
- if ( *pdwAccountName <= dwSrcLen )
- {
- *pdwAccountName = dwSrcLen + 1;
+ /* One or two buffers are insufficient, add up a char for NULL termination */
+ *pdwAccountName = dwAccountName + 1;
+ *pdwDomainName = dwDomainName + 1;
- ret = FALSE;
+ ret = FALSE;
- }
- else
+ } else
- {
+ {
- *pdwAccountName = dwSrcLen;
- if (pAccountName)
- {
- RtlCopyMemory ( pAccountName, TranslatedName->Name.Buffer, TranslatedName->Name.Length );
- pAccountName[TranslatedName->Name.Length / sizeof(WCHAR)] = L'\0';
- }
- }
+ /* Lengths are sufficient, copy the data */
+ if(dwAccountName)
+ RtlCopyMemory(pAccountName, TranslatedName->Name.Buffer, dwAccountName * sizeof(WCHAR));
+ pAccountName[dwAccountName] = L'\0';
+
+ if(dwDomainName)
+ RtlCopyMemory(pDomainName, ReferencedDomain->Domains[0].Name.Buffer, dwDomainName * sizeof(WCHAR));
+ pDomainName[dwDomainName] = L'\0';
+
+ *pdwAccountName = dwAccountName;
+ *pdwDomainName = dwDomainName;
+
- if (peUse)
+ if ( peUse )
*peUse = TranslatedName->Use;
}
-
+
- if ( ReferencedDomain )
- {
- if ( ReferencedDomain->Entries > 0 )
- {
- DWORD dwSrcLen = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR);
- if ( *pdwDomainName <= dwSrcLen )
- {
- *pdwDomainName = dwSrcLen + 1;
- ret = FALSE;
- }
- else
- {
- *pdwDomainName = dwSrcLen;
- if (pDomainName)
- {
- RtlCopyMemory ( pDomainName, ReferencedDomain->Domains[0].Name.Buffer, ReferencedDomain->Domains[0].Name.Length );
- pDomainName[ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR)] = L'\0';
- }
- }
- }
- }
-
if ( !ret )
SetLastError(ERROR_INSUFFICIENT_BUFFER);
}
LRESULT CToolbarProxy::OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
-- LRESULT result;
++ LONG result;
HRESULT hResult;
result = 0;
TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes);
needed = bytes + pad_bytes + 1;
- needed += (needed / 64 + 1) * strlen(sep);
+ if (sep)
+ needed += (needed / 64 + 1) * strlen(sep);
if (needed > *out_len)
{
*ptr++ = '=';
break;
}
- strcpy(ptr, sep);
+ if (sep)
+ strcpy(ptr, sep);
return ERROR_SUCCESS;
}
charsNeeded = 0;
encodeBase64A(pbBinary, cbBinary, sep, NULL, &charsNeeded);
- charsNeeded += strlen(sep);
+ if (sep)
+ charsNeeded += strlen(sep);
if (header)
charsNeeded += strlen(header) + strlen(sep);
if (trailer)
{
strcpy(ptr, header);
ptr += strlen(ptr);
- strcpy(ptr, sep);
- ptr += strlen(sep);
- }
+ if (sep)
+ {
+ strcpy(ptr, sep);
+ ptr += strlen(sep);
+ }
+ }
encodeBase64A(pbBinary, cbBinary, sep, ptr, &size);
ptr += size - 1;
if (trailer)
{
strcpy(ptr, trailer);
ptr += strlen(ptr);
- strcpy(ptr, sep);
- ptr += strlen(sep);
- }
+ if (sep)
+ {
+ strcpy(ptr, sep);
+ ptr += strlen(sep);
+ }
+ }
*pcchString = charsNeeded - 1;
}
else if (pszString)
}
}
else
- ret = compare_cert_by_name(pCertContext,
- CERT_COMPARE_NAME | CERT_COMPARE_SUBJECT_CERT, dwFlags,
- &subject->pCertInfo->Issuer);
- return ret;
+ found = cert_compare_certs_in_store(store, prev,
+ compare_cert_by_name, CERT_COMPARE_NAME | CERT_COMPARE_SUBJECT_CERT,
+ dwFlags, &subject->pCertInfo->Issuer);
+ return found;
}
- static BOOL compare_existing_cert(PCCERT_CONTEXT pCertContext, DWORD dwType,
- DWORD dwFlags, const void *pvPara)
+ static BOOL compare_cert_by_name_str(PCCERT_CONTEXT pCertContext,
+ DWORD dwType, DWORD dwFlags, const void *pvPara)
{
- PCCERT_CONTEXT toCompare = pvPara;
- return CertCompareCertificate(pCertContext->dwCertEncodingType,
- pCertContext->pCertInfo, toCompare->pCertInfo);
+ PCERT_NAME_BLOB name;
+ DWORD len;
+ BOOL ret = FALSE;
+
+ if (dwType & CERT_INFO_SUBJECT_FLAG)
+ name = &pCertContext->pCertInfo->Subject;
+ else
+ name = &pCertContext->pCertInfo->Issuer;
+ len = CertNameToStrW(pCertContext->dwCertEncodingType, name,
+ CERT_SIMPLE_NAME_STR, NULL, 0);
+ if (len)
+ {
+ LPWSTR str = CryptMemAlloc(len * sizeof(WCHAR));
+
+ if (str)
+ {
+ LPWSTR ptr;
+
+ CertNameToStrW(pCertContext->dwCertEncodingType, name,
+ CERT_SIMPLE_NAME_STR, str, len);
+ for (ptr = str; *ptr; ptr++)
+ *ptr = tolowerW(*ptr);
+ if (strstrW(str, pvPara))
+ ret = TRUE;
+ CryptMemFree(str);
- }
++}
+ }
+ return ret;
}
- static BOOL compare_cert_by_signature_hash(PCCERT_CONTEXT pCertContext, DWORD dwType,
- DWORD dwFlags, const void *pvPara)
+ static PCCERT_CONTEXT find_cert_by_name_str(HCERTSTORE store, DWORD dwType,
+ DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
{
- const CRYPT_HASH_BLOB *hash = pvPara;
- DWORD size = 0;
- BOOL ret;
+ PCCERT_CONTEXT found = NULL;
- ret = CertGetCertificateContextProperty(pCertContext,
- CERT_SIGNATURE_HASH_PROP_ID, NULL, &size);
- if (ret && size == hash->cbData)
+ TRACE("%s\n", debugstr_w(pvPara));
+
+ if (pvPara)
{
- LPBYTE buf = CryptMemAlloc(size);
+ DWORD len = strlenW(pvPara);
+ LPWSTR str = CryptMemAlloc((len + 1) * sizeof(WCHAR));
- if (buf)
+ if (str)
{
- CertGetCertificateContextProperty(pCertContext,
- CERT_SIGNATURE_HASH_PROP_ID, buf, &size);
- ret = !memcmp(buf, hash->pbData, size);
- CryptMemFree(buf);
+ LPCWSTR src;
+ LPWSTR dst;
+
+ for (src = pvPara, dst = str; *src; src++, dst++)
+ *dst = tolowerW(*src);
+ *dst = 0;
+ found = cert_compare_certs_in_store(store, prev,
+ compare_cert_by_name_str, dwType, dwFlags, str);
+ CryptMemFree(str);
}
}
else
break;
default:
FIXME("find type %08x unimplemented\n", dwType);
- compare = NULL;
}
- if (compare)
- {
- BOOL matches = FALSE;
-
- ret = pPrevCertContext;
- do {
- ret = CertEnumCertificatesInStore(hCertStore, ret);
- if (ret)
- matches = compare(ret, dwType, dwFlags, pvPara);
- } while (ret != NULL && !matches);
- if (!ret)
- SetLastError(CRYPT_E_NOT_FOUND);
- }
+ if (find)
+ ret = find(hCertStore, dwFlags, dwType, pvPara, pPrevCertContext);
+ else if (compare)
+ ret = cert_compare_certs_in_store(hCertStore, pPrevCertContext,
+ compare, dwType, dwFlags, pvPara);
else
- {
- SetLastError(CRYPT_E_NOT_FOUND);
ret = NULL;
- }
- if (!ret)
- SetLastError(CRYPT_E_NOT_FOUND);
++ if (!ret)
++ SetLastError(CRYPT_E_NOT_FOUND);
TRACE("returning %p\n", ret);
return ret;
}
assert(pSubjectIssuerBlob);
assert(pubKey);
- info->dwVersion = CERT_V3;
+ if (pExtensions && pExtensions->cExtension)
+ info->dwVersion = CERT_V3;
+ else
+ info->dwVersion = CERT_V1;
info->SerialNumber.cbData = pSerialNumber->cbData;
info->SerialNumber.pbData = pSerialNumber->pbData;
if (pSignatureAlgorithm)
cert = CertEnumCertificatesInStore(store, cert);
if (cert)
{
- size = sizeof(hash);
-
- ret = CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID,
- hash, &size);
- if (ret)
- {
- CRYPT_HASH_BLOB blob = { sizeof(hash), hash };
-
- check = CertFindCertificateInStore(rootStore,
- cert->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob,
- NULL);
- if (!check)
+ if (!(check = CRYPT_FindCertInStore(rootStore, cert)))
- ret = FALSE;
- else
- CertFreeCertificateContext(check);
- }
+ ret = FALSE;
+ else
+ CertFreeCertificateContext(check);
+ }
- }
} while (ret && cert);
if (cert)
CertFreeCertificateContext(cert);
if ((nameConstraints = CRYPT_GetNameConstraints(
chain->rgpElement[i]->pCertContext->pCertInfo)))
{
- for (j = i - 1; j >= 0; j--)
- {
- DWORD errorStatus = 0;
+ if (!CRYPT_IsValidNameConstraint(nameConstraints))
+ chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
+ CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT;
+ else
+ {
+ for (j = i - 1; j >= 0; j--)
+ {
+ DWORD errorStatus = 0;
- /* According to RFC 3280, self-signed certs don't have name
- * constraints checked unless they're the end cert.
- */
- if (j == 0 || !CRYPT_IsCertificateSelfSigned(
- chain->rgpElement[j]->pCertContext))
- {
- CRYPT_CheckNameConstraints(nameConstraints,
+ /* According to RFC 3280, self-signed certs don't have name
+ * constraints checked unless they're the end cert.
+ */
+ if (j == 0 || !CRYPT_IsCertificateSelfSigned(
+ chain->rgpElement[j]->pCertContext))
+ {
+ CRYPT_CheckNameConstraints(nameConstraints,
- chain->rgpElement[i]->pCertContext->pCertInfo,
+ chain->rgpElement[j]->pCertContext->pCertInfo,
- &errorStatus);
- chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
- errorStatus;
- }
+ &errorStatus);
+ chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
+ errorStatus;
}
}
++ }
LocalFree(nameConstraints);
}
}
return alternate;
}
- #define CHAIN_QUALITY_SIGNATURE_VALID 8
- #define CHAIN_QUALITY_TIME_VALID 4
- #define CHAIN_QUALITY_COMPLETE_CHAIN 2
+ #define CHAIN_QUALITY_SIGNATURE_VALID 0x16
+ #define CHAIN_QUALITY_TIME_VALID 8
+ #define CHAIN_QUALITY_COMPLETE_CHAIN 4
+ #define CHAIN_QUALITY_BASIC_CONSTRAINTS 2
-#define CHAIN_QUALITY_TRUSTED_ROOT 1
+#define CHAIN_QUALITY_TRUSTED_ROOT 1
#define CHAIN_QUALITY_HIGHEST \
CHAIN_QUALITY_SIGNATURE_VALID | CHAIN_QUALITY_TIME_VALID | \
PBASE_CONTEXT baseContext = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
InterlockedIncrement(&baseContext->ref);
- }
+ TRACE("%p's ref count is %d\n", context, baseContext->ref);
+ if (baseContext->type == ContextTypeLink)
+ {
+ void *linkedContext = Context_GetLinkedContext(context, contextSize);
+ PBASE_CONTEXT linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
+ contextSize);
+
+ /* Add-ref the linked contexts too */
+ while (linkedContext && linkedBase->type == ContextTypeLink)
+ {
+ InterlockedIncrement(&linkedBase->ref);
+ TRACE("%p's ref count is %d\n", linkedContext, linkedBase->ref);
+ linkedContext = Context_GetLinkedContext(linkedContext,
+ contextSize);
+ if (linkedContext)
+ linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
+ contextSize);
+ else
+ linkedBase = NULL;
++}
+ if (linkedContext)
+ {
+ /* It's not a link context, so it wasn't add-ref'ed in the while
+ * loop, so add-ref it here.
+ */
+ linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
+ contextSize);
+ InterlockedIncrement(&linkedBase->ref);
+ TRACE("%p's ref count is %d\n", linkedContext, linkedBase->ref);
+ }
+ }
}
void *Context_GetExtra(const void *context, size_t contextSize)
ContextFreeFunc dataContextFree)
{
PBASE_CONTEXT base = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
+ BOOL ret = TRUE;
- if (InterlockedDecrement(&base->ref) == 0)
+ if (base->ref <= 0)
{
- TRACE("freeing %p\n", context);
- switch (base->type)
+ ERR("%p's ref count is %d\n", context, base->ref);
+ return FALSE;
+ }
+ if (base->type == ContextTypeLink)
- {
- /* The linked context is of the same type as this, so release
- * it as well, using the same offset and data free function.
- */
+ {
- case ContextTypeData:
- ContextPropertyList_Free(((PDATA_CONTEXT)base)->properties);
- dataContextFree(context);
- break;
- case ContextTypeLink:
+ /* The linked context is of the same type as this, so release
+ * it as well, using the same offset and data free function.
+ */
- Context_Release(CONTEXT_FROM_BASE_CONTEXT(
+ ret = Context_Release(CONTEXT_FROM_BASE_CONTEXT(
- ((PLINK_CONTEXT)base)->linked, contextSize), contextSize,
- dataContextFree);
- }
+ ((PLINK_CONTEXT)base)->linked, contextSize), contextSize,
+ dataContextFree);
- break;
- default:
- assert(0);
++ }
+ if (InterlockedDecrement(&base->ref) == 0)
+ {
+ TRACE("freeing %p\n", context);
+ if (base->type == ContextTypeData)
+ {
+ ContextPropertyList_Free(((PDATA_CONTEXT)base)->properties);
+ dataContextFree(context);
}
CryptMemFree(context);
}
return ret;
}
- void ContextList_Delete(struct ContextList *list, void *context)
+ BOOL ContextList_Remove(struct ContextList *list, void *context)
{
struct list *entry = ContextList_ContextToEntry(list, context);
+ BOOL inList = FALSE;
EnterCriticalSection(&list->cs);
- list_remove(entry);
+ if (!list_empty(entry))
+ {
+ list_remove(entry);
+ inList = TRUE;
+ }
LeaveCriticalSection(&list->cs);
- list->contextInterface->free(context);
+ if (inList)
+ list_init(entry);
+ return inList;
}
static void ContextList_Empty(struct ContextList *list)
PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(PCCRL_CONTEXT pCrlContext)
{
TRACE("(%p)\n", pCrlContext);
- Context_AddRef((void *)pCrlContext, sizeof(CRL_CONTEXT));
+ if (pCrlContext)
+ Context_AddRef((void *)pCrlContext, sizeof(CRL_CONTEXT));
return pCrlContext;
}
PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext)
{
TRACE("(%p)\n", pCtlContext);
- Context_AddRef((void *)pCtlContext, sizeof(CTL_CONTEXT));
+ if (pCtlContext)
+ Context_AddRef((void *)pCtlContext, sizeof(CTL_CONTEXT));
return pCtlContext;
}
: NULL, &items[i].size, &itemDecoded);
if (ret)
{
- /* Account for alignment padding */
- items[i].size = ALIGN_DWORD_PTR(items[i].size);
+ if (items[i].size < items[i].minSize)
+ items[i].size = items[i].minSize;
+ else if (items[i].size > items[i].minSize)
+ {
+ /* Account for alignment padding */
+ items[i].size = ALIGN_DWORD_PTR(items[i].size);
+ }
TRACE("item %d size: %d\n", i, items[i].size);
if (nextData && items[i].hasPointer &&
items[i].size > items[i].minSize)
{
BOOL ret = TRUE;
+ TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
__TRY
{
- ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
- dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
- if (ret && pvStructInfo)
- {
- ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
- pcbStructInfo, *pcbStructInfo);
- if (ret)
- {
- CERT_EXTENSIONS *exts;
-
- if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
- pvStructInfo = *(BYTE **)pvStructInfo;
- exts = pvStructInfo;
- exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
- sizeof(CERT_EXTENSIONS));
- ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
- dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
- pcbStructInfo, NULL);
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_EXTENSIONS, cExtension),
+ offsetof(CERT_EXTENSIONS, rgExtension),
+ sizeof(CERT_EXTENSIONS),
+ CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
+ offsetof(CERT_EXTENSION, pszObjId) };
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
- }
+ }
- }
- }
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
__TRY
{
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
+ sizeof(CERT_NAME_INFO),
CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
offsetof(CERT_RDN, rgRDNAttr) };
+ DWORD bytesNeeded;
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
+ NULL);
+ if (ret)
+ {
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
+ pvStructInfo, pcbStructInfo, bytesNeeded)))
+ {
+ CERT_NAME_INFO *info;
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+ info = pvStructInfo;
+ info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
+ sizeof(CERT_NAME_INFO));
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
+ &bytesNeeded, NULL);
- }
++ }
+ }
}
__EXCEPT_PAGE_FAULT
{
__TRY
{
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
+ sizeof(CERT_NAME_INFO),
CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
offsetof(CERT_RDN, rgRDNAttr) };
+ DWORD bytesNeeded;
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
+ NULL);
+ if (ret)
+ {
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
+ pvStructInfo, pcbStructInfo, bytesNeeded)))
+ {
+ CERT_NAME_INFO *info;
+
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+ info = pvStructInfo;
+ info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
+ sizeof(CERT_NAME_INFO));
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
+ &bytesNeeded, NULL);
- }
++ }
+ }
}
__EXCEPT_PAGE_FAULT
{
__TRY
{
- DWORD bytesNeeded;
-
- if (!cbEncoded)
- SetLastError(CRYPT_E_ASN1_EOD);
- else if (pbEncoded[0] != ASN_SEQUENCEOF)
- SetLastError(CRYPT_E_ASN1_CORRUPT);
- else if ((ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
- cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
- NULL)))
- {
- if (!pvStructInfo)
- *pcbStructInfo = bytesNeeded;
- else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
- pvStructInfo, pcbStructInfo, bytesNeeded)))
- {
- PCRYPT_SMIME_CAPABILITIES capabilities;
-
- if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
- pvStructInfo = *(BYTE **)pvStructInfo;
- capabilities = pvStructInfo;
- capabilities->rgCapability =
- (PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo +
- sizeof(CRYPT_SMIME_CAPABILITIES));
- ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
- cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
- &bytesNeeded, NULL);
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
+ offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
+ sizeof(CRYPT_SMIME_CAPABILITIES),
+ CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
+ offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
- }
+ }
- }
- }
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
__TRY
{
- DWORD bytesNeeded;
+ struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
+ offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
+ sizeof(CRYPT_ATTRIBUTES),
+ CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE),
+ TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
- if (!cbEncoded)
- SetLastError(CRYPT_E_ASN1_EOD);
- else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
- SetLastError(CRYPT_E_ASN1_CORRUPT);
- else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
- cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
- NULL)))
- {
- if (!pvStructInfo)
- *pcbStructInfo = bytesNeeded;
- else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
- pvStructInfo, pcbStructInfo, bytesNeeded)))
- {
- PCRYPT_ATTRIBUTES attrs;
-
- if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
- pvStructInfo = *(BYTE **)pvStructInfo;
- attrs = pvStructInfo;
- attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
- sizeof(CRYPT_ATTRIBUTES));
- ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
- cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
- &bytesNeeded, NULL);
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
- }
+ }
- }
- }
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
case 1: /* rfc822Name */
case 2: /* dNSName */
case 6: /* uniformResourceIdentifier */
- bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
+ if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen))
+ {
+ SetLastError(CRYPT_E_ASN1_RULE);
+ ret = FALSE;
+ }
+ else
+ bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
break;
case 4: /* directoryName */
case 7: /* iPAddress */
{
DWORD len = CRYPT_GetMultiStringCharacterLen(multi);
- /* Copy remainder of string "left" */
- memmove(spotToRemove, spotToRemove + lstrlenW(toRemove) + 1,
- (len - (spotToRemove - multi)) * sizeof(WCHAR));
+ if (spotToRemove + lstrlenW(toRemove) + 2 >= multi + len)
+ {
+ /* Removing last string in list, terminate multi string directly */
+ *spotToRemove = 0;
+ *(spotToRemove + 1) = 0;
+ }
+ else
+ {
+ /* Copy remainder of string "left" */
+ memmove(spotToRemove, spotToRemove + lstrlenW(toRemove) + 1,
+ (len - (spotToRemove - multi)) * sizeof(WCHAR));
+ }
ret = TRUE;
}
else
CERT_STORE_ADD_NEW, &context);
}
else
- ret = CRYPT_ReadContextProp(contextInterface,
- context, &propHdr, buf, read);
+ {
+ if (!contextInterface)
+ {
+ WARN("prop id %d before a context id\n",
+ propHdr.propID);
+ ret = FALSE;
- }
++ }
+ else
+ ret = CRYPT_ReadContextProp(
+ contextInterface, context, &propHdr, buf,
+ read);
- }
++ }
}
}
else
*brush = GdipAlloc(sizeof(GpHatch));
if (!*brush) return OutOfMemory;
- switch (hatchstyle)
+ if (hatchstyle < sizeof(HatchBrushes) / sizeof(HatchBrushes[0]))
{
- case HatchStyleHorizontal:
- case HatchStyleVertical:
- case HatchStyleForwardDiagonal:
- case HatchStyleBackwardDiagonal:
- case HatchStyleCross:
- case HatchStyleDiagonalCross:
- /* Brushes that map to BS_HATCHED */
- (*brush)->brush.lb.lbStyle = BS_HATCHED;
- (*brush)->brush.lb.lbColor = fgcol;
- (*brush)->brush.lb.lbHatch = HatchStyleToHatch(hatchstyle);
- break;
+ HBITMAP hbmp;
+ HDC hdc;
+ BITMAPINFOHEADER bmih;
+ DWORD* bits;
+ int x, y;
- default:
+ hdc = CreateCompatibleDC(0);
+
+ if (hdc)
+ {
+ bmih.biSize = sizeof(bmih);
+ bmih.biWidth = 8;
+ bmih.biHeight = 8;
+ bmih.biPlanes = 1;
+ bmih.biBitCount = 32;
+ bmih.biCompression = BI_RGB;
+ bmih.biSizeImage = 0;
+
+ hbmp = CreateDIBSection(hdc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+
+ if (hbmp)
+ {
+ for (y=0; y<8; y++)
+ for (x=0; x<8; x++)
+ if ((HatchBrushes[hatchstyle][y] & (0x80 >> x)) != 0)
+ bits[y*8+x] = forecol;
+ else
+ bits[y*8+x] = backcol;
+ }
+ else
+ stat = GenericError;
+
+ DeleteDC(hdc);
+ }
+ else
+ stat = GenericError;
+
+ if (stat == Ok)
+ {
+ (*brush)->brush.lb.lbStyle = BS_PATTERN;
+ (*brush)->brush.lb.lbColor = 0;
+ (*brush)->brush.lb.lbHatch = (ULONG_PTR)hbmp;
+ (*brush)->brush.gdibrush = CreateBrushIndirect(&(*brush)->brush.lb);
+
+ DeleteObject(hbmp);
+ }
+ }
+ else
+ {
- FIXME("Unimplemented hatch style %d\n", hatchstyle);
+ FIXME("Unimplemented hatch style %d\n", hatchstyle);
- (*brush)->brush.lb.lbStyle = BS_SOLID;
- (*brush)->brush.lb.lbColor = fgcol;
- (*brush)->brush.lb.lbHatch = 0;
+ (*brush)->brush.lb.lbStyle = BS_SOLID;
+ (*brush)->brush.lb.lbColor = fgcol;
+ (*brush)->brush.lb.lbHatch = 0;
- break;
+ (*brush)->brush.gdibrush = CreateBrushIndirect(&(*brush)->brush.lb);
}
-
- (*brush)->brush.gdibrush = CreateBrushIndirect(&(*brush)->brush.lb);
+ if (stat == Ok)
+ {
- (*brush)->brush.bt = BrushTypeHatchFill;
- (*brush)->forecol = forecol;
- (*brush)->backcol = backcol;
- (*brush)->hatchstyle = hatchstyle;
+ (*brush)->brush.bt = BrushTypeHatchFill;
+ (*brush)->forecol = forecol;
+ (*brush)->backcol = backcol;
+ (*brush)->hatchstyle = hatchstyle;
+ }
+ else
+ {
+ GdipFree(*brush);
+ *brush = NULL;
+ }
- return Ok;
+ return stat;
}
/******************************************************************************
/* start_angle and end_angle are the iterative variables */
start_angle = startAngle;
- for(i = 0; i < count - 1; i += 3){
+ for(i = 0; i < MAX_ARC_PTS - 1; i += 3){
/* check if we've overshot the end angle */
if( sweepAngle > 0.0 )
+ {
+ if (start_angle >= endAngle) break;
end_angle = min(start_angle + M_PI_2, endAngle);
+ }
else
+ {
+ if (start_angle <= endAngle) break;
end_angle = max(start_angle - M_PI_2, endAngle);
+ }
- add_arc_part(&points[i], x1, y1, x2, y2, start_angle, end_angle, i == 0);
+ if (points)
+ add_arc_part(&points[i], x1, y1, x2, y2, start_angle, end_angle, i == 0);
start_angle += M_PI_2 * (sweepAngle < 0.0 ? -1.0 : 1.0);
}
<library>ole32</library>
<library>user32</library>
<library>gdi32</library>
- <library>kernel32</library>
<library>windowscodecs</library>
<library>ntdll</library>
+ <if property="ARCH" value="amd64">
+ <library>crt</library>
+ </if>
</module>
</group>
blendfac = (left_blendfac * (right_blendpos - position) +
right_blendfac * (position - left_blendpos)) / range;
}
- return blend_colors(brush->startcolor, brush->endcolor, blendfac);
+
+ if (brush->pblendcount == 0)
- }
+ return blend_colors(brush->startcolor, brush->endcolor, blendfac);
+ else
+ {
+ int i=1;
+ ARGB left_blendcolor, right_blendcolor;
+ REAL left_blendpos, right_blendpos;
+
+ /* locate the blend colors surrounding this position */
+ while (blendfac > brush->pblendpos[i])
+ i++;
+
+ /* interpolate between the blend colors */
+ left_blendpos = brush->pblendpos[i-1];
+ left_blendcolor = brush->pblendcolor[i-1];
+ right_blendpos = brush->pblendpos[i];
+ right_blendcolor = brush->pblendcolor[i];
+ blendfac = (blendfac - left_blendpos) / (right_blendpos - left_blendpos);
+ return blend_colors(left_blendcolor, right_blendcolor, blendfac);
++}
}
static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y,
ARGB *color)
{
- static int calls;
+ BYTE r, g, b, a;
+ BYTE *row;
TRACE("%p %d %d %p\n", bitmap, x, y, color);
- if(!bitmap || !color)
+ if(!bitmap || !color ||
+ x < 0 || y < 0 || x >= bitmap->width || y >= bitmap->height)
return InvalidParameter;
- if(!(calls++))
- FIXME("not implemented\n");
-
- *color = 0xdeadbeef;
+ row = bitmap->bits+bitmap->stride*y;
- return NotImplemented;
- }
+ switch (bitmap->format)
+ {
+ case PixelFormat16bppGrayScale:
+ getpixel_16bppGrayScale(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat16bppRGB555:
+ getpixel_16bppRGB555(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat16bppRGB565:
+ getpixel_16bppRGB565(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat16bppARGB1555:
+ getpixel_16bppARGB1555(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat24bppRGB:
+ getpixel_24bppRGB(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat32bppRGB:
+ getpixel_32bppRGB(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat32bppARGB:
+ getpixel_32bppARGB(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat32bppPARGB:
+ getpixel_32bppPARGB(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat48bppRGB:
+ getpixel_48bppRGB(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat64bppARGB:
+ getpixel_64bppARGB(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat64bppPARGB:
+ getpixel_64bppPARGB(&r,&g,&b,&a,row,x);
+ break;
+ default:
+ FIXME("not implemented for format 0x%x\n", bitmap->format);
+ return NotImplemented;
+}
+ *color = a<<24|r<<16|g<<8|b;
+
+ return Ok;
+ }
+
+ static inline void setpixel_16bppGrayScale(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+ {
+ *((WORD*)(row)+x) = (r+g+b)*85;
+ }
+
+ static inline void setpixel_16bppRGB555(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+ {
+ *((WORD*)(row)+x) = (r<<7&0x7c00)|
+ (g<<2&0x03e0)|
+ (b>>3&0x001f);
+ }
+
+ static inline void setpixel_16bppRGB565(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+ {
+ *((WORD*)(row)+x) = (r<<8&0xf800)|
+ (g<<3&0x07e0)|
+ (b>>3&0x001f);
+ }
+
+ static inline void setpixel_16bppARGB1555(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+ {
+ *((WORD*)(row)+x) = (a<<8&0x8000)|
+ (r<<7&0x7c00)|
+ (g<<2&0x03e0)|
+ (b>>3&0x001f);
+ }
+
+ static inline void setpixel_24bppRGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+ {
+ row[x*3+2] = r;
+ row[x*3+1] = g;
+ row[x*3] = b;
+ }
+
+ static inline void setpixel_32bppRGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+ {
+ *((DWORD*)(row)+x) = (r<<16)|(g<<8)|b;
+ }
+
+ static inline void setpixel_32bppARGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+ {
+ *((DWORD*)(row)+x) = (a<<24)|(r<<16)|(g<<8)|b;
+ }
+
+ static inline void setpixel_32bppPARGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+ {
+ r = r * a / 255;
+ g = g * a / 255;
+ b = b * a / 255;
+ *((DWORD*)(row)+x) = (a<<24)|(r<<16)|(g<<8)|b;
+ }
+
+ static inline void setpixel_48bppRGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+ {
+ row[x*6+5] = row[x*6+4] = r;
+ row[x*6+3] = row[x*6+2] = g;
+ row[x*6+1] = row[x*6] = b;
+ }
+
+ static inline void setpixel_64bppARGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+ {
+ UINT64 a64=a, r64=r, g64=g, b64=b;
+ *((UINT64*)(row)+x) = (a64<<56)|(a64<<48)|(r64<<40)|(r64<<32)|(g64<<24)|(g64<<16)|(b64<<8)|b64;
+ }
+
+ static inline void setpixel_64bppPARGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+ {
+ UINT64 a64, r64, g64, b64;
+ a64 = a * 257;
+ r64 = r * a / 255;
+ g64 = g * a / 255;
+ b64 = b * a / 255;
+ *((UINT64*)(row)+x) = (a64<<48)|(r64<<32)|(g64<<16)|b64;
+ }
+
GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y,
ARGB color)
{
- static int calls;
+ BYTE a, r, g, b;
+ BYTE *row;
TRACE("bitmap:%p, x:%d, y:%d, color:%08x\n", bitmap, x, y, color);
- if(!bitmap)
+ if(!bitmap || x < 0 || y < 0 || x >= bitmap->width || y >= bitmap->height)
return InvalidParameter;
- if(!(calls++))
- FIXME("not implemented\n");
+ a = color>>24;
+ r = color>>16;
+ g = color>>8;
+ b = color;
+
+ row = bitmap->bits + bitmap->stride * y;
- return NotImplemented;
- }
+ switch (bitmap->format)
+ {
+ case PixelFormat16bppGrayScale:
+ setpixel_16bppGrayScale(r,g,b,a,row,x);
+ break;
+ case PixelFormat16bppRGB555:
+ setpixel_16bppRGB555(r,g,b,a,row,x);
+ break;
+ case PixelFormat16bppRGB565:
+ setpixel_16bppRGB565(r,g,b,a,row,x);
+ break;
+ case PixelFormat16bppARGB1555:
+ setpixel_16bppARGB1555(r,g,b,a,row,x);
+ break;
+ case PixelFormat24bppRGB:
+ setpixel_24bppRGB(r,g,b,a,row,x);
+ break;
+ case PixelFormat32bppRGB:
+ setpixel_32bppRGB(r,g,b,a,row,x);
+ break;
+ case PixelFormat32bppARGB:
+ setpixel_32bppARGB(r,g,b,a,row,x);
+ break;
+ case PixelFormat32bppPARGB:
+ setpixel_32bppPARGB(r,g,b,a,row,x);
+ break;
+ case PixelFormat48bppRGB:
+ setpixel_48bppRGB(r,g,b,a,row,x);
+ break;
+ case PixelFormat64bppARGB:
+ setpixel_64bppARGB(r,g,b,a,row,x);
+ break;
+ case PixelFormat64bppPARGB:
+ setpixel_64bppPARGB(r,g,b,a,row,x);
+ break;
+ default:
+ FIXME("not implemented for format 0x%x\n", bitmap->format);
+ return NotImplemented;
+}
+ return Ok;
+ }
+
/* This function returns a pointer to an array of pixels that represents the
* bitmap. The *entire* bitmap is locked according to the lock mode specified by
* flags. It is correct behavior that a user who calls this function with write
return decode_image_wic(stream, &CLSID_WICIcoDecoder, image);
}
- static GpStatus decode_image_jpeg(IStream* stream, REFCLSID clsid, GpImage **image)
- {
- return decode_image_wic(stream, &CLSID_WICJpegDecoder, image);
- }
-
- static GpStatus decode_image_gif(IStream* stream, REFCLSID clsid, GpImage **image)
- {
- return decode_image_wic(stream, &CLSID_WICGifDecoder, image);
- }
-
- static GpStatus decode_image_olepicture_bitmap(IStream* stream, REFCLSID clsid, GpImage **image)
+ static GpStatus decode_image_bmp(IStream* stream, REFCLSID clsid, GpImage **image)
{
- IPicture *pic;
- BITMAPINFO *pbmi;
- BITMAPCOREHEADER* bmch;
- HBITMAP hbm;
- HDC hdc;
+ GpStatus status;
+ GpBitmap* bitmap;
- TRACE("%p %p\n", stream, image);
+ status = decode_image_wic(stream, &CLSID_WICBmpDecoder, image);
- if(!stream || !image)
- return InvalidParameter;
+ bitmap = (GpBitmap*)*image;
- if(OleLoadPicture(stream, 0, FALSE, &IID_IPicture,
- (LPVOID*) &pic) != S_OK){
- TRACE("Could not load picture\n");
- return GenericError;
+ if (status == Ok && bitmap->format == PixelFormat32bppARGB)
- {
++{
+ /* WIC supports bmp files with alpha, but gdiplus does not */
+ bitmap->format = PixelFormat32bppRGB;
}
- pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
- if (!pbmi)
- return OutOfMemory;
- *image = GdipAlloc(sizeof(GpBitmap));
- if(!*image){
- GdipFree(pbmi);
- return OutOfMemory;
+ return status;
-}
+ }
- (*image)->type = ImageTypeBitmap;
-
- (*((GpBitmap**) image))->width = ipicture_pixel_width(pic);
- (*((GpBitmap**) image))->height = ipicture_pixel_height(pic);
- /* get the pixel format */
- IPicture_get_Handle(pic, (OLE_HANDLE*)&hbm);
- IPicture_get_CurDC(pic, &hdc);
-
- (*((GpBitmap**) image))->hbitmap = hbm;
- (*((GpBitmap**) image))->hdc = hdc;
- (*((GpBitmap**) image))->bits = NULL;
-
- bmch = (BITMAPCOREHEADER*) (&pbmi->bmiHeader);
- bmch->bcSize = sizeof(BITMAPCOREHEADER);
-
- if(!hdc){
- HBITMAP old;
- hdc = CreateCompatibleDC(0);
- old = SelectObject(hdc, hbm);
- GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
- SelectObject(hdc, old);
- DeleteDC(hdc);
+ static GpStatus decode_image_jpeg(IStream* stream, REFCLSID clsid, GpImage **image)
+ {
+ return decode_image_wic(stream, &CLSID_WICJpegDecoder, image);
-}
+ }
- else
- GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
- switch(bmch->bcBitCount)
+ static GpStatus decode_image_png(IStream* stream, REFCLSID clsid, GpImage **image)
-{
+ {
- case 1:
- (*((GpBitmap**) image))->format = PixelFormat1bppIndexed;
- break;
- case 4:
- (*((GpBitmap**) image))->format = PixelFormat4bppIndexed;
- break;
- case 8:
- (*((GpBitmap**) image))->format = PixelFormat8bppIndexed;
- break;
- case 16:
- (*((GpBitmap**) image))->format = PixelFormat16bppRGB565;
- break;
- case 24:
- (*((GpBitmap**) image))->format = PixelFormat24bppRGB;
- break;
- case 32:
- (*((GpBitmap**) image))->format = PixelFormat32bppRGB;
- break;
- case 48:
- (*((GpBitmap**) image))->format = PixelFormat48bppRGB;
- break;
- default:
- FIXME("Bit depth %d is not fully supported yet\n", bmch->bcBitCount);
- (*((GpBitmap**) image))->format = (bmch->bcBitCount << 8) | PixelFormatGDI;
- break;
+ return decode_image_wic(stream, &CLSID_WICPngDecoder, image);
-}
+ }
- GdipFree(pbmi);
-
- (*image)->picture = pic;
- (*image)->flags = ImageFlagsNone;
-
- return Ok;
+ static GpStatus decode_image_gif(IStream* stream, REFCLSID clsid, GpImage **image)
+ {
+ return decode_image_wic(stream, &CLSID_WICGifDecoder, image);
}
static GpStatus decode_image_olepicture_metafile(IStream* stream, REFCLSID clsid, GpImage **image)
if (FAILED(hr)) return hresult_to_status(hr);
/* call on the image decoder to do the real work */
- return codec->decode_func(stream, &codec->info.Clsid, image);
+ stat = codec->decode_func(stream, &codec->info.Clsid, image);
+
+ /* take note of the original data format */
+ if (stat == Ok)
+ {
+ memcpy(&(*image)->format, &codec->info.FormatID, sizeof(GUID));
- }
++}
+
+ return stat;
}
/* FIXME: no ICM */
BasepCheckForReadOnlyResource(IN PVOID Ptr)
{
PVOID Data;
-- ULONG Size, OldProtect;
++ SIZE_T Size;
++ ULONG OldProtect;
MEMORY_BASIC_INFORMATION mbi;
NTSTATUS Status;
LONG Ret = EXCEPTION_CONTINUE_SEARCH;
@ stdcall AddAtomW(wstr)
@ stdcall AddConsoleAliasA(str str str) ;check
@ stdcall AddConsoleAliasW(wstr wstr wstr) ;check
+;@ stdcall -arch=x86_64 AddIntegrityLabelToBoundaryDescriptor ; Win 7
@ stdcall AddLocalAlternateComputerNameA(str ptr)
@ stdcall AddLocalAlternateComputerNameW(wstr ptr)
- ;@ stdcall AddRefActCtx(ptr)
+ @ stdcall AddRefActCtx(ptr)
+;@ stdcall AddSIDToBoundaryDescriptor ; Win 7
+;@ stdcall AddSecureMemoryCacheCallback ; Win 7
@ stdcall AddVectoredContinueHandler(long ptr) ntdll.RtlAddVectoredContinueHandler
@ stdcall AddVectoredExceptionHandler(long ptr) ntdll.RtlAddVectoredExceptionHandler
+;@ stdcall AdjustCalendarDate ; Win 7
@ stdcall AllocConsole()
-@ stub AllocLSCallback ; missing in XP SP3 and 2003 R2
+@ stub AllocLSCallback ; missing in XP SP3 and 2003 R2 and Win 7
@ stdcall AllocateUserPhysicalPages(long ptr ptr)
+;@ stdcall AllocateUserPhysicalPagesNuma ; Win 7
+;@ stdcall ApplicationRecoveryFinished ; Win 7
+;@ stdcall ApplicationRecoveryInProgress ; Win 7
@ stdcall AreFileApisANSI()
@ stdcall AssignProcessToJobObject(ptr ptr)
@ stdcall AttachConsole(long)
@ stdcall CopyFileA(str str long)
@ stdcall CopyFileExA (str str ptr ptr ptr long)
@ stdcall CopyFileExW (wstr wstr ptr ptr ptr long)
+;@ stdcall CopyFileTransactedA ; Win 7
+;@ stdcall CopyFileTransactedW ; Win 7
@ stdcall CopyFileW(wstr wstr long)
@ stdcall CopyLZFile(long long) LZCopy
- ;@ stdcall CreateActCtxA(ptr)
- ;@ stdcall CreateActCtxW(ptr)
+ @ stdcall CreateActCtxA(ptr)
+ @ stdcall CreateActCtxW(ptr)
+;@ stdcall CreateBoundaryDescriptorA ; Win 7
+;@ stdcall CreateBoundaryDescriptorW ; Win 7
@ stdcall CreateConsoleScreenBuffer(long long ptr long ptr)
@ stdcall CreateDirectoryA(str ptr)
@ stdcall CreateDirectoryExA(str str ptr)
@ stdcall CreateTimerQueue ()
@ stdcall CreateTimerQueueTimer(ptr long ptr ptr long long long)
@ stdcall CreateToolhelp32Snapshot(long long)
-@ stdcall CreateVirtualBuffer(long long long)
+;@ stdcall arch=x86_64 CreateUmsCompletionList
+;@ stdcall arch=x86_64 CreateUmsThreadContext
+@ stdcall CreateVirtualBuffer(long long long) ; missing in Win 7
@ stdcall CreateWaitableTimerA(ptr long str)
-@ stdcall CreateWaitableTimerW(ptr long wstr)
@ stdcall CreateWaitableTimerExA (ptr str long long)
@ stdcall CreateWaitableTimerExW (ptr wstr long long)
- @ stdcall CreateWaitableTimerW(ptr long wstr)
+ @ stdcall DeactivateActCtx(long ptr)
+;@ stdcall CtrlRoutine ; Win 7
- ;@ stdcall DeactivateActCtx(long ptr)
@ stdcall DebugActiveProcess(long)
@ stdcall DebugActiveProcessStop(long)
@ stdcall DebugBreak() ntdll.DbgBreakPoint
@ stdcall GetConsoleTitleW(ptr long)
@ stdcall GetConsoleWindow()
@ stdcall GetCurrencyFormatA(long long str ptr str long)
+;@ stdcall GetCurrencyFormatEx ; Win 7
@ stdcall GetCurrencyFormatW(long long str ptr str long)
- ;@ stdcall GetCurrentActCtx(ptr)
+ @ stdcall GetCurrentActCtx(ptr)
@ stdcall GetCurrentConsoleFont(long long ptr)
+;@ stdcall GetCurrentConsoleFontEx ; Win 7
@ stdcall GetCurrentDirectoryA(long ptr)
@ stdcall GetCurrentDirectoryW(long ptr)
@ stdcall GetCurrentProcess()
@ stdcall LocalShrink(long long)
@ stdcall LocalSize(long)
@ stdcall LocalUnlock(long)
- @ stub LocaleNameToLCID ; missing in XP SP3
+ ;@ stub LocaleNameToLCID ; missing in XP SP3
+;@ stdcall LocateExtendedFeature api-ms-win-core-xstate-l1-1-0.RtlLocateExtendedFeature ; Win 7
+;@ stdcall LocateLegacyContext api-ms-win-core-xstate-l1-1-0.RtlLocateLegacyContext ; Win 7
@ stdcall LockFile(long long long long long)
@ stdcall LockFileEx(long long long long long ptr)
@ stdcall LockResource(long)
@ stdcall ProcessIdToSessionId(long ptr)
@ stdcall PulseEvent(long)
@ stdcall PurgeComm(long long)
- ;@ stdcall QueryActCtxW(long ptr ptr long ptr long ptr)
+;@ stdcall QueryActCtxSettingsW ; Win 7
+ @ stdcall QueryActCtxW(long ptr ptr long ptr long ptr)
@ stdcall QueryDepthSList(ptr) ntdll.RtlQueryDepthSList
@ stdcall QueryDosDeviceA(str ptr long)
@ stdcall QueryDosDeviceW(wstr ptr long)
@ stdcall RegisterWaitForSingleObjectEx(long ptr ptr long long)
@ stdcall RegisterWowBaseHandlers(long)
@ stdcall RegisterWowExec(long)
- ;@ stdcall ReleaseActCtx(ptr)
+ @ stdcall ReleaseActCtx(ptr)
@ stdcall ReleaseMutex(long)
-@ stdcall ReleaseSemaphore(long long ptr)
+;@ stdcall ReleaseMutexWhenCallbackReturns ntdll.TpCallbackReleaseMutexOnCompletion ; Win 7
@ stdcall ReleaseSRWLockExclusive(ptr) ntdll.RtlReleaseSRWLockExclusive
@ stdcall ReleaseSRWLockShared(ptr) ntdll.RtlReleaseSRWLockShared
+@ stdcall ReleaseSemaphore(long long ptr)
+;@ stdcall ReleaseSemaphoreWhenCallbackReturns ntdll.TpCallbackReleaseSemaphoreOnCompletion ; Win 7
@ stdcall RemoveDirectoryA(str)
+;@ stdcall RemoveDirectoryTransactedA ; Win 7
+;@ stdcall RemoveDirectoryTransactedW ; Win 7
@ stdcall RemoveDirectoryW(wstr)
@ stdcall RemoveLocalAlternateComputerNameA(str long)
@ stdcall RemoveLocalAlternateComputerNameW(wstr long)
@ stdcall WriteProfileStringA(str str str)
@ stdcall WriteProfileStringW(wstr wstr wstr)
@ stdcall WriteTapemark(ptr long long long)
-@ stdcall WTSGetActiveConsoleSessionId()
+@ stdcall WTSGetActiveConsoleSessionId() ; missing in win 7
- ;@ stdcall ZombifyActCtx(ptr)
+ @ stdcall ZombifyActCtx(ptr)
-@ stub _DebugOut ; missing in XP SP3
-@ stub _DebugPrintf ; missing in XP SP3
+;@ stdcall -arch=x86_64 __C_specific_handler ntdll.__C_specific_handler
+;@ stdcall -arch=x86_64 __chkstk ntdll.__chkstk
+;@ stdcall -arch=x86_64 __misaligned_access ntdll.__misaligned_access
+@ stub _DebugOut ; missing in XP SP3 and Win 7
+@ stub _DebugPrintf ; missing in XP SP3 and Win 7
@ stdcall _hread(long ptr long)
@ stdcall _hwrite(long ptr long)
@ stdcall _lclose(long)
* Eric Pouech
* Jon Griffiths
* Dmitry Chapyshev (dmitry@reactos.org)
+ * Samuel Serapión
*/
+ /* synched with wine 1.1.26 */
+
#include <k32.h>
- #define NDEBUG
- #include <debug.h>
+ #include "wine/debug.h"
- #define ACTCTX_FLAGS_ALL (\
- ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID |\
- ACTCTX_FLAG_LANGID_VALID |\
- ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID |\
- ACTCTX_FLAG_RESOURCE_NAME_VALID |\
- ACTCTX_FLAG_SET_PROCESS_DEFAULT |\
- ACTCTX_FLAG_APPLICATION_NAME_VALID |\
- ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF |\
- ACTCTX_FLAG_HMODULE_VALID )
+ WINE_DEFAULT_DEBUG_CHANNEL(actctx);
#define ACTCTX_FAKE_HANDLE ((HANDLE) 0xf00baa)
- #define ACTCTX_FAKE_COOKIE ((ULONG_PTR) 0xf00bad)
- /*
- * @implemented
+ /***********************************************************************
+ * CreateActCtxA (KERNEL32.@)
+ *
+ * Create an activation context.
*/
- BOOL
- WINAPI
- FindActCtxSectionStringA(
- DWORD dwFlags,
- const GUID *lpExtensionGuid,
- ULONG ulSectionId,
- LPCSTR lpStringToFind,
- PACTCTX_SECTION_KEYED_DATA ReturnedData
- )
+ HANDLE WINAPI CreateActCtxA(PCACTCTXA pActCtx)
{
- BOOL bRetVal;
- LPWSTR lpStringToFindW = NULL;
+ ACTCTXW actw;
+ SIZE_T len;
+ HANDLE ret = INVALID_HANDLE_VALUE;
+ LPWSTR src = NULL, assdir = NULL, resname = NULL, appname = NULL;
+
+ TRACE("%p %08x\n", pActCtx, pActCtx ? pActCtx->dwFlags : 0);
- /* Convert lpStringToFind */
- if (lpStringToFind)
+ if (!pActCtx || pActCtx->cbSize != sizeof(*pActCtx))
{
- BasepAnsiStringToHeapUnicodeString(lpStringToFind,
- (LPWSTR*) &lpStringToFindW);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return INVALID_HANDLE_VALUE;
}
- /* Call the Unicode function */
- bRetVal = FindActCtxSectionStringW(dwFlags,
- lpExtensionGuid,
- ulSectionId,
- lpStringToFindW,
- ReturnedData);
-
- /* Clean up */
- if (lpStringToFindW)
- RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpStringToFindW);
-
- return bRetVal;
- }
-
-
- /*
- * @implemented
- */
- HANDLE
- WINAPI
- CreateActCtxA(
- PCACTCTXA pActCtx
- )
- {
- ACTCTXW pActCtxW;
- HANDLE hRetVal;
-
- ZeroMemory(&pActCtxW, sizeof(ACTCTXW));
- pActCtxW.cbSize = sizeof(ACTCTXW);
- pActCtxW.dwFlags = pActCtx->dwFlags;
- pActCtxW.wLangId = pActCtx->wLangId;
- pActCtxW.hModule = pActCtx->hModule;
- pActCtxW.wProcessorArchitecture = pActCtx->wProcessorArchitecture;
-
- pActCtxW.hModule = pActCtx->hModule;
-
- /* Convert ActCtx Strings */
+ actw.cbSize = sizeof(actw);
+ actw.dwFlags = pActCtx->dwFlags;
if (pActCtx->lpSource)
{
- BasepAnsiStringToHeapUnicodeString(pActCtx->lpSource,
- (LPWSTR*) &pActCtxW.lpSource);
+ len = MultiByteToWideChar(CP_ACP, 0, pActCtx->lpSource, -1, NULL, 0);
+ src = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!src) return INVALID_HANDLE_VALUE;
+ MultiByteToWideChar(CP_ACP, 0, pActCtx->lpSource, -1, src, len);
}
- if (pActCtx->lpAssemblyDirectory)
+ actw.lpSource = src;
+
+ if (actw.dwFlags & ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID)
+ actw.wProcessorArchitecture = pActCtx->wProcessorArchitecture;
+ if (actw.dwFlags & ACTCTX_FLAG_LANGID_VALID)
+ actw.wLangId = pActCtx->wLangId;
+ if (actw.dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID)
{
- BasepAnsiStringToHeapUnicodeString(pActCtx->lpAssemblyDirectory,
- (LPWSTR*) &pActCtxW.lpAssemblyDirectory);
+ len = MultiByteToWideChar(CP_ACP, 0, pActCtx->lpAssemblyDirectory, -1, NULL, 0);
+ assdir = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!assdir) goto done;
+ MultiByteToWideChar(CP_ACP, 0, pActCtx->lpAssemblyDirectory, -1, assdir, len);
+ actw.lpAssemblyDirectory = assdir;
}
- if (HIWORD(pActCtx->lpResourceName))
+ if (actw.dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID)
{
- BasepAnsiStringToHeapUnicodeString(pActCtx->lpResourceName,
- (LPWSTR*) &pActCtxW.lpResourceName);
- }
- else
+ if ((ULONG_PTR)pActCtx->lpResourceName >> 16)
- {
+ {
- pActCtxW.lpResourceName = (LPWSTR) pActCtx->lpResourceName;
+ len = MultiByteToWideChar(CP_ACP, 0, pActCtx->lpResourceName, -1, NULL, 0);
+ resname = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!resname) goto done;
+ MultiByteToWideChar(CP_ACP, 0, pActCtx->lpResourceName, -1, resname, len);
+ actw.lpResourceName = resname;
- }
+ }
- if (pActCtx->lpApplicationName)
+ else actw.lpResourceName = (LPCWSTR)pActCtx->lpResourceName;
+ }
+ if (actw.dwFlags & ACTCTX_FLAG_APPLICATION_NAME_VALID)
{
- BasepAnsiStringToHeapUnicodeString(pActCtx->lpApplicationName,
- (LPWSTR*) &pActCtxW.lpApplicationName);
+ len = MultiByteToWideChar(CP_ACP, 0, pActCtx->lpApplicationName, -1, NULL, 0);
+ appname = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!appname) goto done;
+ MultiByteToWideChar(CP_ACP, 0, pActCtx->lpApplicationName, -1, appname, len);
+ actw.lpApplicationName = appname;
}
- /* Call the Unicode function */
- hRetVal = CreateActCtxW(&pActCtxW);
+ if (actw.dwFlags & ACTCTX_FLAG_HMODULE_VALID)
+ actw.hModule = pActCtx->hModule;
- /* Clean up */
- RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) pActCtxW.lpSource);
- RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) pActCtxW.lpAssemblyDirectory);
- if (HIWORD(pActCtx->lpResourceName))
- RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) pActCtxW.lpResourceName);
- RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) pActCtxW.lpApplicationName);
+ ret = CreateActCtxW(&actw);
- return hRetVal;
+ done:
+ HeapFree(GetProcessHeap(), 0, src);
+ HeapFree(GetProcessHeap(), 0, assdir);
+ HeapFree(GetProcessHeap(), 0, resname);
+ HeapFree(GetProcessHeap(), 0, appname);
+ return ret;
}
- /*
- * @unimplemented
+ /***********************************************************************
+ * CreateActCtxW (KERNEL32.@)
+ *
+ * Create an activation context.
*/
- BOOL
- WINAPI
- ActivateActCtx(
- HANDLE hActCtx,
- ULONG_PTR *ulCookie
- )
+ HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
{
- NTSTATUS Status;
+ NTSTATUS status;
+ HANDLE hActCtx;
- DPRINT("ActivateActCtx(%p %p)\n", hActCtx, ulCookie );
+ TRACE("%p %08x\n", pActCtx, pActCtx ? pActCtx->dwFlags : 0);
- Status = RtlActivateActivationContext(0, hActCtx, ulCookie);
- if (!NT_SUCCESS(Status))
+ if ((status = RtlCreateActivationContext(&hActCtx, (PVOID*)pActCtx)))
{
- SetLastError(RtlNtStatusToDosError(Status));
+ SetLastError(RtlNtStatusToDosError(status));
+ return INVALID_HANDLE_VALUE;
+ }
+ return hActCtx;
+ }
+
+ /***********************************************************************
+ * ActivateActCtx (KERNEL32.@)
+ *
+ * Activate an activation context.
+ */
+ BOOL WINAPI ActivateActCtx(HANDLE hActCtx, ULONG_PTR *ulCookie)
+ {
+ NTSTATUS status;
+
+ if ((status = RtlActivateActivationContext( 0, hActCtx, ulCookie )))
+ {
+ SetLastError(RtlNtStatusToDosError(status));
return FALSE;
}
return TRUE;
return TRUE;
}
- /*
- * @unimplemented
+ /***********************************************************************
+ * FindActCtxSectionGuid (KERNEL32.@)
+ *
+ * Find information about a GUID in an activation context.
*/
- BOOL
- WINAPI
- QueryActCtxW(
- DWORD dwFlags,
- HANDLE hActCtx,
- PVOID pvSubInstance,
- ULONG ulInfoClass,
- PVOID pvBuffer,
- SIZE_T cbBuffer OPTIONAL,
- SIZE_T *pcbWrittenOrRequired OPTIONAL
- )
+ BOOL WINAPI FindActCtxSectionGuid(DWORD dwFlags, const GUID* lpExtGuid,
+ ULONG ulId, const GUID* lpSearchGuid,
+ PACTCTX_SECTION_KEYED_DATA pInfo)
{
- DPRINT("%s() is UNIMPLEMENTED!\n", __FUNCTION__);
- /* this makes Adobe Photoshop 7.0 happy */
+ FIXME("%08x %s %u %s %p\n", dwFlags, debugstr_guid(lpExtGuid),
+ ulId, debugstr_guid(lpSearchGuid), pInfo);
- SetLastError( ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
- /*
- * @unimplemented
+ /***********************************************************************
+ * QueryActCtxW (KERNEL32.@)
+ *
+ * Get information about an activation context.
*/
- VOID
- WINAPI
- ReleaseActCtx(
- HANDLE hActCtx
- )
+ BOOL WINAPI QueryActCtxW(DWORD dwFlags, HANDLE hActCtx, PVOID pvSubInst,
+ ULONG ulClass, PVOID pvBuff, SIZE_T cbBuff,
+ SIZE_T *pcbLen)
{
- DPRINT("ReleaseActCtx(%p)\n", hActCtx);
- RtlReleaseActivationContext(hActCtx);
- }
+ NTSTATUS status;
- /*
- * @unimplemented
- */
- BOOL
- WINAPI
- ZombifyActCtx(
- HANDLE hActCtx
- )
+ if ((status = RtlQueryInformationActivationContext( dwFlags, hActCtx, pvSubInst, ulClass,
+ pvBuff, cbBuff, pcbLen )))
- {
+{
- NTSTATUS Status;
- DPRINT("ZombifyActCtx(%p)\n", hActCtx);
-
- Status = RtlZombifyActivationContext(hActCtx);
- if (!NT_SUCCESS(Status))
- {
- SetLastError(RtlNtStatusToDosError(Status));
+ SetLastError(RtlNtStatusToDosError(status));
return FALSE;
}
-
return TRUE;
}
TRACE("module = %p, id = %08x\n", module, id );
if (!module) module = GetModuleHandleW( NULL );
- Status = RtlFindMessage( module, (ULONG) RT_MESSAGETABLE, lang, id, &mre );
+ Status = RtlFindMessage( module, (ULONG_PTR) RT_MESSAGETABLE, lang, id, &mre );
if (!NT_SUCCESS(Status))
+ {
+ SetLastError( RtlNtStatusToDosError(Status) );
return NULL;
+ }
if (mre->Flags & MESSAGE_RESOURCE_UNICODE)
{
TRACE("module = %p, id = %08x\n", module, id );
if (!module) module = GetModuleHandleW( NULL );
- Status = RtlFindMessage( module, (ULONG) RT_MESSAGETABLE, lang, id, &mre );
+ Status = RtlFindMessage( module, (ULONG_PTR) RT_MESSAGETABLE, lang, id, &mre );
if (!NT_SUCCESS(Status))
+ {
+ SetLastError( RtlNtStatusToDosError(Status) );
return NULL;
+ }
if (mre->Flags & MESSAGE_RESOURCE_UNICODE)
{
/* Get the TEB */
Status = NtQueryInformationThread(hThread,
- ThreadBasicIformation,
+ ThreadBasicInformation,
&ThreadBasicInfo,
sizeof(ThreadBasicInfo),
- NULL);
-
+ &retLen);
+ if (NT_SUCCESS(Status))
+ {
- /* Allocate the Activation Context Stack */
- Status = RtlAllocateActivationContextStack(&ActivationContextStack);
+ /* Allocate the Activation Context Stack */
+ Status = RtlAllocateActivationContextStack(&ActivationContextStack);
+ }
+
+ if (NT_SUCCESS(Status))
+ {
- Teb = ThreadBasicInfo.TebBaseAddress;
-
- /* Save it */
- Teb->ActivationContextStackPointer = ActivationContextStack;
-
- /* Query the Context */
- Status = RtlQueryInformationActivationContext(1,
- 0,
- NULL,
- ActivationContextBasicInformation,
- &ActivationCtxInfo,
- sizeof(ActivationCtxInfo),
+ Teb = ThreadBasicInfo.TebBaseAddress;
+
+ /* Save it */
+ Teb->ActivationContextStackPointer = ActivationContextStack;
+
+ /* Query the Context */
+ Status = RtlQueryInformationActivationContext(1,
+ 0,
+ NULL,
+ ActivationContextBasicInformation,
+ &ActivationCtxInfo,
+ sizeof(ActivationCtxInfo),
- NULL);
-
+ &retLen);
+ if (NT_SUCCESS(Status))
+ {
- /* Does it need to be activated? */
- if (!ActivationCtxInfo.hActCtx)
- {
- /* Activate it */
+ /* Does it need to be activated? */
+ if (!ActivationCtxInfo.hActCtx)
+ {
+ /* Activate it */
- Status = RtlActivateActivationContextEx(1,
- Teb,
+ Status = RtlActivateActivationContext(1,
- ActivationCtxInfo.hActCtx,
- &Cookie);
+ ActivationCtxInfo.hActCtx,
+ &Cookie);
+ if (!NT_SUCCESS(Status))
+ DPRINT1("RtlActivateActivationContext failed %x\n", Status);
- }
- }
++ }
++ }
+ else
+ DPRINT1("RtlQueryInformationActivationContext failed %x\n", Status);
}
+ else
+ DPRINT1("RtlAllocateActivationContextStack failed %x\n", Status);
}
#endif
return This->data->vtbl->invoke(This->outer, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
if(wFlags == DISPATCH_CONSTRUCT) {
- FIXME("DISPATCH_CONSTRUCT not implemented\n");
- return E_NOTIMPL;
+ if(id == DISPID_VALUE) {
+ if(This->data->vtbl && This->data->vtbl->value) {
+ return This->data->vtbl->value(This->outer, lcid, wFlags, pdp,
+ pvarRes, pei, pspCaller);
- }
++ }
+ FIXME("DISPATCH_CONSTRUCT flag but missing value function\n");
+ return E_FAIL;
+ }
+ FIXME("DISPATCH_CONSTRUCT flag without DISPID_VALUE\n");
+ return E_FAIL;
}
if(is_dynamic_dispid(id)) {
if(FAILED(hres))
return hres;
- doc->nscontainer = NSContainer_Create(doc, NULL);
- list_init(&doc->bindings);
- doc->usermode = UNKNOWN_USERMODE;
- doc->readystate = READYSTATE_UNINITIALIZED;
-
- if(doc->nscontainer) {
- nsresult nsres;
- nsres = nsIWebBrowser_GetContentDOMWindow(doc->nscontainer->webbrowser, &nswindow);
- if(NS_FAILED(nsres))
- ERR("GetContentDOMWindow failed: %08x\n", nsres);
+ nsres = nsIWebBrowser_GetContentDOMWindow(doc->nscontainer->webbrowser, &nswindow);
+ if(NS_FAILED(nsres))
+ ERR("GetContentDOMWindow failed: %08x\n", nsres);
- }
- hres = HTMLWindow_Create(doc, nswindow, &doc->basedoc.window);
+ hres = HTMLWindow_Create(doc, nswindow, NULL /* FIXME */, &doc->basedoc.window);
if(nswindow)
nsIDOMWindow_Release(nswindow);
if(FAILED(hres)) {
TRACE("(%p)->(%p)\n", This, p);
- if(!This->content_window) {
- nsIDOMHTMLDocument *nshtmldoc;
- HTMLDocumentNode *content_doc;
- nsIDOMDocument *nsdoc;
- HTMLWindow *window;
- nsresult nsres;
- HRESULT hres;
-
- nsres = nsIDOMHTMLIFrameElement_GetContentDocument(This->nsiframe, &nsdoc);
- if(NS_FAILED(nsres)) {
- ERR("GetContentDocument failed: %08x\n", nsres);
- return E_FAIL;
- }
-
- if(!nsdoc) {
- FIXME("NULL contentDocument\n");
- return E_FAIL;
- }
-
- nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMHTMLDocument, (void**)&nshtmldoc);
- nsIDOMDocument_Release(nsdoc);
- if(NS_FAILED(nsres)) {
- ERR("Could not get nsIDOMHTMLDocument iface: %08x\n", nsres);
- return E_FAIL;
- }
-
- hres = create_content_window(This, nshtmldoc, &window);
- if(FAILED(hres)) {
- nsIDOMHTMLDocument_Release(nshtmldoc);
- return E_FAIL;
+ if(This->framebase.content_window) {
+ IHTMLWindow2_AddRef(HTMLWINDOW2(This->framebase.content_window));
+ *p = HTMLWINDOW2(This->framebase.content_window);
+ }else {
+ WARN("NULL content window\n");
+ *p = NULL;
- }
+ }
-
- hres = create_doc_from_nsdoc(nshtmldoc, This->element.node.doc->basedoc.doc_obj, window, &content_doc);
- nsIDOMHTMLDocument_Release(nshtmldoc);
- if(SUCCEEDED(hres))
- window_set_docnode(window, content_doc);
- else
- IHTMLWindow2_Release(HTMLWINDOW2(window));
- htmldoc_release(&content_doc->basedoc);
- if(FAILED(hres))
- return hres;
-
- This->content_window = window;
- }
-
- IHTMLWindow2_AddRef(HTMLWINDOW2(This->content_window));
- *p = HTMLWINDOW2(This->content_window);
return S_OK;
}
static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v)
{
HTMLLocation *This = HTMLLOCATION_THIS(iface);
- FIXME("(%p)->(%s)\n", This, debugstr_w(v));
- return E_NOTIMPL;
+
+ TRACE("(%p)->(%s)\n", This, debugstr_w(v));
+
+ if(!This->window || !This->window->doc) {
+ FIXME("No document available\n");
+ return E_FAIL;
- }
++}
+
+ return navigate_url(This->window->doc, v);
}
static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p)
if(FAILED(hres))
return hres;
- *p = SysAllocString(url);
- return *p ? S_OK : E_OUTOFMEMORY;
+ switch(url.nScheme) {
+ case INTERNET_SCHEME_FILE:
+ {
+ /* prepend a slash */
+ url_path = HeapAlloc(GetProcessHeap(), 0, (url.dwUrlPathLength + 1) * sizeof(WCHAR));
+ if(!url_path)
+ return E_OUTOFMEMORY;
+ url_path[0] = '/';
+ memcpy(url_path + 1, url.lpszUrlPath, url.dwUrlPathLength * sizeof(WCHAR));
+ url.lpszUrlPath = url_path;
+ url.dwUrlPathLength = url.dwUrlPathLength + 1;
- }
++}
+ break;
+
+ case INTERNET_SCHEME_HTTP:
+ case INTERNET_SCHEME_HTTPS:
+ case INTERNET_SCHEME_FTP:
+ if(!url.dwUrlPathLength) {
+ /* add a slash if it's blank */
+ url_path = url.lpszUrlPath = HeapAlloc(GetProcessHeap(), 0, 1 * sizeof(WCHAR));
+ if(!url.lpszUrlPath)
+ return E_OUTOFMEMORY;
+ url.lpszUrlPath[0] = '/';
+ url.dwUrlPathLength = 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* replace \ with / */
+ for(i = 0; i < url.dwUrlPathLength; ++i)
+ if(url.lpszUrlPath[i] == '\\')
+ url.lpszUrlPath[i] = '/';
+
+ if(InternetCreateUrlW(&url, ICU_ESCAPE, NULL, &len)) {
+ FIXME("InternetCreateUrl succeeded with NULL buffer?\n");
+ ret = E_FAIL;
+ goto cleanup;
+ }
+
+ if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ FIXME("InternetCreateUrl failed with error: %08x\n", GetLastError());
+ SetLastError(0);
+ ret = E_FAIL;
+ goto cleanup;
+ }
+ SetLastError(0);
+
+ buf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if(!buf) {
+ ret = E_OUTOFMEMORY;
+ goto cleanup;
+ }
+
+ if(!InternetCreateUrlW(&url, ICU_ESCAPE, buf, &len)) {
+ FIXME("InternetCreateUrl failed with error: %08x\n", GetLastError());
+ SetLastError(0);
+ ret = E_FAIL;
+ goto cleanup;
+ }
+
+ *p = SysAllocStringLen(buf, len);
+ if(!*p) {
+ ret = E_OUTOFMEMORY;
+ goto cleanup;
+ }
+
+ ret = S_OK;
+
+ cleanup:
+ HeapFree(GetProcessHeap(), 0, buf);
+ HeapFree(GetProcessHeap(), 0, url_path);
+
+ return ret;
}
static HRESULT WINAPI HTMLLocation_put_protocol(IHTMLLocation *iface, BSTR v)
if(!p)
return E_POINTER;
- return E_NOTIMPL;
+ url.dwSchemeLength = 1;
+ hres = get_url_components(This, &url);
+ if(FAILED(hres))
+ return hres;
+
+ if(!url.dwSchemeLength) {
+ FIXME("Unexpected blank protocol\n");
- }
+ return E_NOTIMPL;
+ }else {
+ WCHAR buf[url.dwSchemeLength + 1];
+ memcpy(buf, url.lpszScheme, url.dwSchemeLength * sizeof(WCHAR));
+ buf[url.dwSchemeLength] = ':';
+ *p = SysAllocStringLen(buf, url.dwSchemeLength + 1);
++}
+ if(!*p)
+ return E_OUTOFMEMORY;
+ return S_OK;
}
static HRESULT WINAPI HTMLLocation_put_host(IHTMLLocation *iface, BSTR v)
if(!p)
return E_POINTER;
- return E_NOTIMPL;
+ url.dwHostNameLength = 1;
+ hres = get_url_components(This, &url);
+ if(FAILED(hres))
+ return hres;
+
+ if(!url.dwHostNameLength){
+ *p = NULL;
+ return S_OK;
- }
++}
+
+ if(url.nPort) {
+ /* <hostname>:<port> */
+ const WCHAR format[] = {'%','d',0};
+ DWORD len = url.dwHostNameLength + 1 + 5 + 1;
+ WCHAR buf[len];
+
+ memcpy(buf, url.lpszHostName, url.dwHostNameLength * sizeof(WCHAR));
+ buf[url.dwHostNameLength] = ':';
+ snprintfW(buf + url.dwHostNameLength + 1, 6, format, url.nPort);
+ *p = SysAllocString(buf);
+ }else
+ *p = SysAllocStringLen(url.lpszHostName, url.dwHostNameLength);
+
+ if(!*p)
+ return E_OUTOFMEMORY;
+ return S_OK;
}
static HRESULT WINAPI HTMLLocation_put_hostname(IHTMLLocation *iface, BSTR v)
if(!p)
return E_POINTER;
- return E_NOTIMPL;
+ url.dwHostNameLength = 1;
+ hres = get_url_components(This, &url);
+ if(FAILED(hres))
+ return hres;
+
+ if(!url.dwHostNameLength){
+ *p = NULL;
+ return S_OK;
- }
++}
+
+ *p = SysAllocStringLen(url.lpszHostName, url.dwHostNameLength);
+ if(!*p)
+ return E_OUTOFMEMORY;
+ return S_OK;
}
static HRESULT WINAPI HTMLLocation_put_port(IHTMLLocation *iface, BSTR v)
if(!p)
return E_POINTER;
- return E_NOTIMPL;
+ hres = get_url_components(This, &url);
+ if(FAILED(hres))
+ return hres;
+
+ if(url.nPort) {
+ const WCHAR format[] = {'%','d',0};
+ WCHAR buf[6];
+ snprintfW(buf, 6, format, url.nPort);
+ *p = SysAllocString(buf);
+ }else {
+ const WCHAR empty[] = {0};
+ *p = SysAllocString(empty);
- }
++}
+
+ if(!*p)
+ return E_OUTOFMEMORY;
+ return S_OK;
}
static HRESULT WINAPI HTMLLocation_put_pathname(IHTMLLocation *iface, BSTR v)
if(!p)
return E_POINTER;
- return E_NOTIMPL;
+ url.dwExtraInfoLength = 1;
+ hres = get_url_components(This, &url);
+ if(FAILED(hres))
+ return hres;
+
+ if(!url.dwExtraInfoLength){
+ *p = NULL;
+ return S_OK;
- }
++}
+
+ url.dwExtraInfoLength = strcspnW(url.lpszExtraInfo, hash);
+
+ *p = SysAllocStringLen(url.lpszExtraInfo, url.dwExtraInfoLength);
+
+ if(!*p)
+ return E_OUTOFMEMORY;
+ return S_OK;
}
static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v)
if(!p)
return E_POINTER;
- return E_NOTIMPL;
+ url.dwExtraInfoLength = 1;
+ hres = get_url_components(This, &url);
+ if(FAILED(hres))
+ return hres;
+
+ if(!url.dwExtraInfoLength){
+ *p = NULL;
+ return S_OK;
- }
++}
+
+ hash_pos = strcspnW(url.lpszExtraInfo, hash);
+ url.dwExtraInfoLength -= hash_pos;
+
+ *p = SysAllocStringLen(url.lpszExtraInfo + hash_pos, url.dwExtraInfoLength);
+
+ if(!*p)
+ return E_OUTOFMEMORY;
+ return S_OK;
}
static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL flag)
static HRESULT WINAPI HTMLDOMNode_get_nextSibling(IHTMLDOMNode *iface, IHTMLDOMNode **p)
{
HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
- FIXME("(%p)->(%p)\n", This, p);
- return E_NOTIMPL;
+ nsIDOMNode *nssibling = NULL;
+
+ TRACE("(%p)->(%p)\n", This, p);
+
+ nsIDOMNode_GetNextSibling(This->nsnode, &nssibling);
+ if(nssibling) {
+ *p = HTMLDOMNODE(get_node(This->doc, nssibling, TRUE));
+ IHTMLDOMNode_AddRef(*p);
+ }else {
+ *p = NULL;
- }
++}
+
+ return S_OK;
}
#undef HTMLDOMNODE_THIS
TRACE("(%p)->(%p)\n", This, p);
- *p = (IDispatch*)HTMLDOC(&This->doc->basedoc);
- IDispatch_AddRef(*p);
+ /* FIXME: Better check for document node */
+ if(This == &This->doc->node) {
+ *p = NULL;
+ }else {
+ *p = (IDispatch*)HTMLDOC(&This->doc->basedoc);
+ IDispatch_AddRef(*p);
+ }
return S_OK;
}
node->ref = 1;
node->doc = doc;
- nsIDOMNode_AddRef(nsnode);
+ if(nsnode)
+ nsIDOMNode_AddRef(nsnode);
node->nsnode = nsnode;
node->next = doc->nodes;
window->doc = doc_node;
if(doc_node)
htmldoc_addref(&doc_node->basedoc);
- }
+
+ if(window->doc_obj && window->doc_obj->basedoc.window == window) {
+ if(window->doc_obj->basedoc.doc_node)
+ htmldoc_release(&window->doc_obj->basedoc.doc_node->basedoc);
+ window->doc_obj->basedoc.doc_node = doc_node;
+ if(doc_node)
+ htmldoc_addref(&doc_node->basedoc);
++}
+ }
+
+ nsIDOMWindow *get_nsdoc_window(nsIDOMDocument *nsdoc)
+ {
+ nsIDOMDocumentView *nsdocview;
+ nsIDOMAbstractView *nsview;
+ nsIDOMWindow *nswindow;
+ nsresult nsres;
+
+ nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMDocumentView, (void**)&nsdocview);
+ nsIDOMDocument_Release(nsdoc);
+ if(NS_FAILED(nsres)) {
+ ERR("Could not get nsIDOMDocumentView iface: %08x\n", nsres);
+ return NULL;
+ }
+
+ nsres = nsIDOMDocumentView_GetDefaultView(nsdocview, &nsview);
+ nsIDOMDocumentView_Release(nsview);
+ if(NS_FAILED(nsres)) {
+ ERR("GetDefaultView failed: %08x\n", nsres);
+ return NULL;
+ }
+
+ nsres = nsIDOMAbstractView_QueryInterface(nsview, &IID_nsIDOMWindow, (void**)&nswindow);
+ nsIDOMAbstractView_Release(nsview);
+ if(NS_FAILED(nsres)) {
+ ERR("Coult not get nsIDOMWindow iface: %08x\n", nsres);
+ return NULL;
+ }
+
+ return nswindow;
+ }
+
+ static void release_children(HTMLWindow *This)
+ {
+ HTMLWindow *child;
+
+ while(!list_empty(&This->children)) {
+ child = LIST_ENTRY(list_tail(&This->children), HTMLWindow, sibling_entry);
+
+ list_remove(&child->sibling_entry);
+ child->parent = NULL;
+ IHTMLWindow2_Release(HTMLWINDOW2(child));
+ }
}
#define HTMLWINDOW2_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow2, iface)
static HRESULT WINAPI HTMLWindow2_get_length(IHTMLWindow2 *iface, LONG *p)
{
HTMLWindow *This = HTMLWINDOW2_THIS(iface);
- FIXME("(%p)->(%p)\n", This, p);
- return E_NOTIMPL;
+ nsIDOMWindowCollection *nscollection;
+ PRUint32 length;
+ nsresult nsres;
+
+ TRACE("(%p)->(%p)\n", This, p);
+
+ nsres = nsIDOMWindow_GetFrames(This->nswindow, &nscollection);
+ if(NS_FAILED(nsres)) {
+ ERR("GetFrames failed: %08x\n", nsres);
+ return E_FAIL;
- }
++}
+
+ nsres = nsIDOMWindowCollection_GetLength(nscollection, &length);
+ nsIDOMWindowCollection_Release(nscollection);
+ if(NS_FAILED(nsres)) {
+ ERR("GetLength failed: %08x\n", nsres);
+ return E_FAIL;
+ }
+
+ *p = length;
+ return S_OK;
}
static HRESULT WINAPI HTMLWindow2_get_frames(IHTMLWindow2 *iface, IHTMLFramesCollection2 **p)
static HRESULT WINAPI HTMLWindow2_get_name(IHTMLWindow2 *iface, BSTR *p)
{
HTMLWindow *This = HTMLWINDOW2_THIS(iface);
- FIXME("(%p)->(%p)\n", This, p);
- return E_NOTIMPL;
+ nsAString name_str;
+ nsresult nsres;
+ HRESULT hres;
+
+ TRACE("(%p)->(%p)\n", This, p);
+
+ nsAString_Init(&name_str, NULL);
+ nsres = nsIDOMWindow_GetName(This->nswindow, &name_str);
+ if(NS_SUCCEEDED(nsres)) {
+ const PRUnichar *name;
+
+ nsAString_GetData(&name_str, &name);
+ if(*name) {
+ *p = SysAllocString(name);
+ hres = *p ? S_OK : E_OUTOFMEMORY;
+ }else {
+ *p = NULL;
+ hres = S_OK;
- }
++}
+ }else {
+ ERR("GetName failed: %08x\n", nsres);
+ hres = E_FAIL;
+ }
+ nsAString_Finish(&name_str);
+
+ return hres;
}
static HRESULT WINAPI HTMLWindow2_get_parent(IHTMLWindow2 *iface, IHTMLWindow2 **p)
if(idx >= This->global_prop_cnt)
return DISP_E_MEMBERNOTFOUND;
- disp = get_script_disp(This->global_props[idx].script_host);
+ prop = This->global_props+idx;
+
+ switch(prop->type) {
+ case GLOBAL_SCRIPTVAR: {
+ IDispatchEx *dispex;
+ IDispatch *disp;
+
+ disp = get_script_disp(prop->script_host);
- if(!disp)
- return E_UNEXPECTED;
+ if(!disp)
+ return E_UNEXPECTED;
- hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
- if(SUCCEEDED(hres)) {
+ hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
+ if(SUCCEEDED(hres)) {
- TRACE("%s >>>\n", debugstr_w(This->global_props[idx].name));
- hres = IDispatchEx_InvokeEx(dispex, This->global_props[idx].id, lcid, flags, params, res, ei, caller);
+ TRACE("%s >>>\n", debugstr_w(prop->name));
+ hres = IDispatchEx_InvokeEx(dispex, prop->id, lcid, flags, params, res, ei, caller);
- if(hres == S_OK)
+ if(hres == S_OK)
- TRACE("%s <<<\n", debugstr_w(This->global_props[idx].name));
+ TRACE("%s <<<\n", debugstr_w(prop->name));
- else
+ else
- WARN("%s <<< %08x\n", debugstr_w(This->global_props[idx].name), hres);
+ WARN("%s <<< %08x\n", debugstr_w(prop->name), hres);
- IDispatchEx_Release(dispex);
- }else {
- FIXME("No IDispatchEx\n");
- }
+ IDispatchEx_Release(dispex);
+ }else {
+ FIXME("No IDispatchEx\n");
+ }
+ IDispatch_Release(disp);
+ break;
+ }
+ case GLOBAL_ELEMENTVAR: {
+ IHTMLElement *elem;
+
+ hres = IHTMLDocument3_getElementById(HTMLDOC3(&This->doc->basedoc), prop->name, &elem);
+ if(FAILED(hres))
- return hres;
++ return hres;
+
+ if(!elem)
+ return DISP_E_MEMBERNOTFOUND;
+
+ V_VT(res) = VT_DISPATCH;
+ V_DISPATCH(res) = (IDispatch*)elem;
+ break;
- }
++}
+ default:
+ ERR("invalid type %d\n", prop->type);
+ hres = DISP_E_MEMBERNOTFOUND;
+ }
- IDispatch_Release(disp);
return hres;
}
}
if(find_global_prop(This, bstrName, grfdex, &script_host, &id)) {
- if(This->global_prop_cnt == This->global_prop_size) {
- global_prop_t *new_props;
- DWORD new_size;
-
- if(This->global_props) {
- new_size = This->global_prop_size*2;
- new_props = heap_realloc(This->global_props, new_size*sizeof(global_prop_t));
- }else {
- new_size = 16;
- new_props = heap_alloc(new_size*sizeof(global_prop_t));
- }
- if(!new_props)
+ global_prop_t *prop;
+
+ prop = alloc_global_prop(This, GLOBAL_SCRIPTVAR, bstrName);
+ if(!prop)
- return E_OUTOFMEMORY;
+ return E_OUTOFMEMORY;
- This->global_props = new_props;
- This->global_prop_size = new_size;
+
+ prop->script_host = script_host;
+ prop->id = id;
+
+ *pid = prop_to_dispid(This, prop);
+ return S_OK;
- }
+ }
- This->global_props[This->global_prop_cnt].name = heap_strdupW(bstrName);
- if(!This->global_props[This->global_prop_cnt].name)
- return E_OUTOFMEMORY;
+ hres = IDispatchEx_GetDispID(DISPATCHEX(&This->dispex), bstrName, grfdex, pid);
+ if(hres != DISP_E_UNKNOWNNAME)
+ return hres;
- This->global_props[This->global_prop_cnt].script_host = script_host;
- This->global_props[This->global_prop_cnt].id = id;
+ if(This->doc) {
+ global_prop_t *prop;
+ IHTMLElement *elem;
+
+ hres = IHTMLDocument3_getElementById(HTMLDOC3(&This->doc->basedoc), bstrName, &elem);
+ if(SUCCEEDED(hres) && elem) {
+ IHTMLElement_Release(elem);
+
+ prop = alloc_global_prop(This, GLOBAL_ELEMENTVAR, bstrName);
+ if(!prop)
- return E_OUTOFMEMORY;
++ return E_OUTOFMEMORY;
- *pid = MSHTML_DISPID_CUSTOM_MIN + (This->global_prop_cnt++);
+ *pid = prop_to_dispid(This, prop);
- return S_OK;
- }
+ return S_OK;
+ }
+ }
- return IDispatchEx_GetDispID(DISPATCHEX(&This->dispex), bstrName, grfdex, pid);
+ return DISP_E_UNKNOWNNAME;
}
static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
if(!tmp)
return;
- nscontainer->mutation_queue = tmp->next;
+ doc->mutation_queue = tmp->next;
if(!tmp->next)
- nscontainer->mutation_queue_tail = NULL;
+ doc->mutation_queue_tail = NULL;
- nsISupports_Release(tmp->nsiface);
+ if(tmp->nsiface)
+ nsISupports_Release(tmp->nsiface);
heap_free(tmp);
}
push_mutation_queue(This, MUTATION_COMMENT, (nsISupports*)nscomment);
nsIDOMComment_Release(nscomment);
- add_script_runner(This);
+ }
+
+ nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMHTMLIFrameElement, (void**)&nsiframe);
+ if(NS_SUCCEEDED(nsres)) {
+ TRACE("iframe node\n");
+
+ push_mutation_queue(This, MUTATION_IFRAME, (nsISupports*)nsiframe);
+ nsIDOMHTMLIFrameElement_Release(nsiframe);
- }
++}
+
+ nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMHTMLFrameElement, (void**)&nsframe);
+ if(NS_SUCCEEDED(nsres)) {
+ TRACE("frame node\n");
+
+ push_mutation_queue(This, MUTATION_FRAME, (nsISupports*)nsframe);
+ nsIDOMHTMLFrameElement_Release(nsframe);
}
}
nsDocumentObserver_DoneAddingChildren
};
- void init_mutation(NSContainer *nscontainer)
+ void init_mutation(HTMLDocumentNode *doc)
+ {
+ nsIDOMNSDocument *nsdoc;
+ nsresult nsres;
+
+ doc->lpIDocumentObserverVtbl = &nsDocumentObserverVtbl;
+ doc->lpIRunnableVtbl = &nsRunnableVtbl;
+
+ nsres = nsIDOMHTMLDocument_QueryInterface(doc->nsdoc, &IID_nsIDOMNSDocument, (void**)&nsdoc);
+ if(NS_FAILED(nsres)) {
+ ERR("Could not get nsIDOMNSDocument: %08x\n", nsres);
+ return;
- }
++}
+
+ nsIDOMNSDocument_WineAddObserver(nsdoc, NSDOCOBS(doc));
+ nsIDOMNSDocument_Release(nsdoc);
+ }
+
+ void release_mutation(HTMLDocumentNode *doc)
{
- nscontainer->lpDocumentObserverVtbl = &nsDocumentObserverVtbl;
- nscontainer->lpRunnableVtbl = &nsRunnableVtbl;
+ nsIDOMNSDocument *nsdoc;
+ nsresult nsres;
+
+ nsres = nsIDOMHTMLDocument_QueryInterface(doc->nsdoc, &IID_nsIDOMNSDocument, (void**)&nsdoc);
+ if(NS_FAILED(nsres)) {
+ ERR("Could not get nsIDOMNSDocument: %08x\n", nsres);
+ return;
+ }
+
+ nsIDOMNSDocument_WineRemoveObserver(nsdoc, NSDOCOBS(doc));
+ nsIDOMNSDocument_Release(nsdoc);
}
on_start_nsrequest(This);
- /* events are reset when a new document URI is loaded, so re-initialise them here */
- if(This->bsc.doc && This->bsc.doc->doc_obj->bscallback == This && This->bsc.doc->doc_obj->nscontainer) {
- update_nsdocument(This->bsc.doc->doc_obj);
- init_nsevents(This->bsc.doc->doc_obj->nscontainer);
+ if(This->window)
+ update_window_doc(This->window);
- }
+ }
- }
This->bsc.readed += This->nsstream->buf_size;
if(!hlnf && !exec_shldocvw_67(doc, uri))
return FALSE;
- hres = IOleClientSite_QueryInterface(doc->client, &IID_IServiceProvider,
- (void**)&service_provider);
- if(SUCCEEDED(hres)) {
- IHlinkFrame *hlink_frame;
-
- hres = IServiceProvider_QueryService(service_provider, &IID_IHlinkFrame,
- &IID_IHlinkFrame, (void**)&hlink_frame);
- IServiceProvider_Release(service_provider);
- if(SUCCEEDED(hres)) {
- hlink_frame_navigate(&doc->basedoc, hlink_frame, uri, channel->post_data_stream, hlnf);
- IHlinkFrame_Release(hlink_frame);
-
- return FALSE;
+ hres = hlink_frame_navigate(&doc->basedoc, uri, channel->post_data_stream, hlnf);
+ return hres != S_OK;
-}
+ }
- }
-
- return TRUE;
- }
#define NSCHANNEL_THIS(iface) DEFINE_THIS(nsChannel, HttpChannel, iface)
return NULL;
}
- nsIWineURI_GetNSContainer(wine_uri, &container);
+ nsIWineURI_GetWindow(wine_uri, &window);
nsIWineURI_Release(wine_uri);
- return container;
+ return window;
}
- static nsresult async_open_doc_uri(nsChannel *This, NSContainer *container,
- nsIStreamListener *listener, nsISupports *context, BOOL *open)
+ static HTMLWindow *get_channel_window(nsChannel *This)
{
- IMoniker *mon;
- HRESULT hres;
+ nsIRequestObserver *req_observer;
+ nsIWebProgress *web_progress;
+ nsIDOMWindow *nswindow;
+ HTMLWindow *window;
+ nsresult nsres;
- *open = FALSE;
+ if(!This->load_group) {
+ ERR("NULL load_group\n");
+ return NULL;
+ }
- if(container->bscallback) {
- channelbsc_set_channel(container->bscallback, This, listener, context);
+ nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer);
+ if(NS_FAILED(nsres) || !req_observer) {
+ ERR("GetGroupObserver failed: %08x\n", nsres);
+ return NULL;
+ }
- if(container->doc && container->doc->mime) {
- heap_free(This->content_type);
- This->content_type = heap_strdupWtoA(container->doc->mime);
+ nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress);
+ nsIRequestObserver_Release(req_observer);
+ if(NS_FAILED(nsres)) {
+ ERR("Could not get nsIWebProgress iface: %08x\n", nsres);
+ return NULL;
- }
+ }
- return NS_OK;
- }else {
- BOOL cont = before_async_open(This, container);
-
- if(!cont) {
- TRACE("canceled\n");
- return NS_ERROR_UNEXPECTED;
+ nsres = nsIWebProgress_GetDOMWindow(web_progress, &nswindow);
+ nsIWebProgress_Release(web_progress);
+ if(NS_FAILED(nsres) || !nswindow) {
+ ERR("GetDOMWindow failed: %08x\n", nsres);
+ return NULL;
- }
+ }
- if(!container->doc) {
- return This->channel
- ? nsIChannel_AsyncOpen(This->channel, listener, context)
- : NS_ERROR_UNEXPECTED;
+ window = nswindow_to_window(nswindow);
+ nsIDOMWindow_Release(nswindow);
+
+ if(window)
+ IHTMLWindow2_AddRef(HTMLWINDOW2(window));
+ else
+ FIXME("NULL window for %p\n", nswindow);
+ return window;
-}
+ }
- hres = create_mon_for_nschannel(This, &mon);
- if(FAILED(hres)) {
- return NS_ERROR_UNEXPECTED;
+ typedef struct {
+ task_t header;
+ HTMLDocumentNode *doc;
+ nsChannelBSC *bscallback;
+ } start_binding_task_t;
+
+ static void start_binding_proc(task_t *_task)
+ {
+ start_binding_task_t *task = (start_binding_task_t*)_task;
+
+ start_binding(NULL, task->doc, (BSCallback*)task->bscallback, NULL);
-}
+ }
- set_current_mon(&container->doc->basedoc, mon);
- }
- *open = TRUE;
- return NS_OK;
+ typedef struct {
+ task_t header;
+ HTMLWindow *window;
+ nsChannelBSC *bscallback;
+ } start_doc_binding_task_t;
+
+ static void start_doc_binding_proc(task_t *_task)
+ {
+ start_doc_binding_task_t *task = (start_doc_binding_task_t*)_task;
+
+ start_binding(task->window, NULL, (BSCallback*)task->bscallback, NULL);
+ IUnknown_Release((IUnknown*)task->bscallback);
}
- static nsresult async_open(nsChannel *This, NSContainer *container, nsIStreamListener *listener,
+ static nsresult async_open(nsChannel *This, HTMLWindow *window, BOOL is_doc_channel, nsIStreamListener *listener,
nsISupports *context)
{
nsChannelBSC *bscallback;
channelbsc_set_channel(bscallback, This, listener, context);
- task = heap_alloc(sizeof(task_t));
+ if(is_doc_channel) {
+ start_doc_binding_task_t *task;
- task->doc = &container->doc->basedoc;
- task->task_id = TASK_START_BINDING;
- task->next = NULL;
+ set_window_bscallback(window, bscallback);
+
+ task = heap_alloc(sizeof(start_doc_binding_task_t));
+ task->window = window;
- task->bscallback = bscallback;
+ task->bscallback = bscallback;
+ push_task(&task->header, start_doc_binding_proc, window->task_magic);
+ }else {
+ start_binding_task_t *task = heap_alloc(sizeof(start_binding_task_t));
- push_task(task);
+ task->doc = window->doc;
+ task->bscallback = bscallback;
+ push_task(&task->header, start_binding_proc, window->doc->basedoc.task_magic);
+ }
return NS_OK;
}
return S_OK;
}
- static void set_downloading(HTMLDocumentObj *doc)
+ void parse_complete(HTMLDocumentObj *doc)
{
- IOleCommandTarget *olecmd;
- HRESULT hres;
-
TRACE("(%p)\n", doc);
- if(doc->frame)
- IOleInPlaceFrame_SetStatusText(doc->frame, NULL /* FIXME */);
-
- if(!doc->client)
- return;
-
- hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd);
- if(SUCCEEDED(hres)) {
- VARIANT var;
-
- V_VT(&var) = VT_I4;
- V_I4(&var) = 1;
-
- IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, OLECMDEXECOPT_DONTPROMPTUSER,
- &var, NULL);
- IOleCommandTarget_Release(olecmd);
- }
-
- if(doc->hostui) {
- IDropTarget *drop_target = NULL;
-
- hres = IDocHostUIHandler_GetDropTarget(doc->hostui, NULL /* FIXME */, &drop_target);
- if(drop_target) {
- FIXME("Use IDropTarget\n");
- IDropTarget_Release(drop_target);
- }
-}
+ }
- }
-
- /* Calls undocumented 69 cmd of CGID_Explorer */
- static void call_explorer_69(HTMLDocumentObj *doc)
- {
- IOleCommandTarget *olecmd;
- VARIANT var;
- HRESULT hres;
-
- if(!doc->client)
- return;
-
- hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd);
- if(FAILED(hres))
- return;
-
- VariantInit(&var);
- hres = IOleCommandTarget_Exec(olecmd, &CGID_Explorer, 69, 0, NULL, &var);
- IOleCommandTarget_Release(olecmd);
- if(SUCCEEDED(hres) && V_VT(&var) != VT_NULL)
- FIXME("handle result\n");
- }
-
- static void set_parsecomplete(HTMLDocument *doc)
- {
- IOleCommandTarget *olecmd = NULL;
-
- TRACE("(%p)\n", doc);
-
- if(doc->doc_obj->usermode == EDITMODE)
- init_editor(doc);
-
- call_explorer_69(doc->doc_obj);
- call_property_onchanged(&doc->cp_propnotif, 1005);
- call_explorer_69(doc->doc_obj);
-
- /* FIXME: IE7 calls EnableModelless(TRUE), EnableModelless(FALSE) and sets interactive state here */
-
- doc->doc_obj->readystate = READYSTATE_INTERACTIVE;
- call_property_onchanged(&doc->cp_propnotif, DISPID_READYSTATE);
-
- if(doc->doc_obj->client)
- IOleClientSite_QueryInterface(doc->doc_obj->client, &IID_IOleCommandTarget, (void**)&olecmd);
-
- if(olecmd) {
- VARIANT state, progress;
-
- V_VT(&progress) = VT_I4;
- V_I4(&progress) = 0;
- IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS, OLECMDEXECOPT_DONTPROMPTUSER,
- &progress, NULL);
-
- V_VT(&state) = VT_I4;
- V_I4(&state) = 0;
- IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, OLECMDEXECOPT_DONTPROMPTUSER,
- &state, NULL);
-
- IOleCommandTarget_Exec(olecmd, &CGID_ShellDocView, 103, 0, NULL, NULL);
- IOleCommandTarget_Exec(olecmd, &CGID_MSHTML, IDM_PARSECOMPLETE, 0, NULL, NULL);
- IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_HTTPEQUIV_DONE, 0, NULL, NULL);
-
- IOleCommandTarget_Release(olecmd);
- }
-
- doc->doc_obj->readystate = READYSTATE_COMPLETE;
- call_property_onchanged(&doc->cp_propnotif, DISPID_READYSTATE);
-
- if(doc->doc_obj->frame) {
- static const WCHAR wszDone[] = {'D','o','n','e',0};
- IOleInPlaceFrame_SetStatusText(doc->doc_obj->frame, wszDone);
- }
-
- update_title(doc->doc_obj);
- }
-
- static void set_progress(HTMLDocument *doc)
- {
- IOleCommandTarget *olecmd = NULL;
- HRESULT hres;
-
- TRACE("(%p)\n", doc);
-
- if(doc->doc_obj->client)
- IOleClientSite_QueryInterface(doc->doc_obj->client, &IID_IOleCommandTarget, (void**)&olecmd);
-
- if(olecmd) {
- VARIANT progress_max, progress;
-
- V_VT(&progress_max) = VT_I4;
- V_I4(&progress_max) = 0; /* FIXME */
- IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSMAX, OLECMDEXECOPT_DONTPROMPTUSER,
- &progress_max, NULL);
-
- V_VT(&progress) = VT_I4;
- V_I4(&progress) = 0; /* FIXME */
- IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS, OLECMDEXECOPT_DONTPROMPTUSER,
- &progress, NULL);
- }
-
- if(doc->doc_obj->usermode == EDITMODE && doc->doc_obj->hostui) {
- DOCHOSTUIINFO hostinfo;
-
- memset(&hostinfo, 0, sizeof(DOCHOSTUIINFO));
- hostinfo.cbSize = sizeof(DOCHOSTUIINFO);
- hres = IDocHostUIHandler_GetHostInfo(doc->doc_obj->hostui, &hostinfo);
- if(SUCCEEDED(hres))
- /* FIXME: use hostinfo */
- TRACE("hostinfo = {%u %08x %08x %s %s}\n",
- hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick,
- debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS));
- }
- }
-
- static void task_start_binding(HTMLDocument *doc, BSCallback *bscallback)
- {
- if(doc)
- start_binding(doc, bscallback, NULL);
- IUnknown_Release((IUnknown*)bscallback);
- }
-
- static void process_task(task_t *task)
- {
- switch(task->task_id) {
- case TASK_SETDOWNLOADSTATE:
- set_downloading(task->doc->doc_obj);
- break;
- case TASK_PARSECOMPLETE:
- set_parsecomplete(task->doc);
- break;
- case TASK_SETPROGRESS:
- set_progress(task->doc);
- break;
- case TASK_START_BINDING:
- task_start_binding(task->doc, (BSCallback*)task->bscallback);
- break;
- default:
- ERR("Wrong task_id %d\n", task->task_id);
- }
- }
static void call_timer_disp(IDispatch *disp)
{
return ERROR_FUNCTION_FAILED;
}
- if (!strncmpW(ptr, prefix, prefix_len))
- {
- *flags |= ENV_MOD_APPEND;
- *value += lstrlenW(prefix);
- }
- else if (lstrlenW(*value) >= prefix_len)
+ if (*value)
+ {
+ LPCWSTR ptr = *value;
+ if (!strncmpW(ptr, prefix, prefix_len))
+ {
+ *flags |= ENV_MOD_APPEND;
+ *value += lstrlenW(prefix);
+ }
+ else if (lstrlenW(*value) >= prefix_len)
+ {
+ ptr += lstrlenW(ptr) - prefix_len;
+ if (!lstrcmpW(ptr, prefix))
{
- ptr += lstrlenW(ptr) - prefix_len;
- if (!lstrcmpW(ptr, prefix))
- {
- *flags |= ENV_MOD_PREFIX;
- /* the "[~]" will be removed by deformat_string */;
- }
+ *flags |= ENV_MOD_PREFIX;
+ /* the "[~]" will be removed by deformat_string */;
}
}
++ }
if (check_flag_combo(*flags, ENV_ACT_SETALWAYS | ENV_ACT_SETABSENT) ||
check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETABSENT) ||
lstrcpyW(newval, value);
}
- TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(newval));
- res = RegSetValueExW(env, name, 0, type, (LPVOID)newval, size);
+ if (newval)
+ {
+ TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(newval));
+ res = RegSetValueExW(env, name, 0, type, (LPVOID)newval, size);
+ }
+ else
+ res = ERROR_SUCCESS;
done:
if (env) RegCloseKey(env);
UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature,
MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
{
- FIXME("(%d %s %i %i %p): stub\n", hInstall, debugstr_w(szFeature),
+ MSIPACKAGE *package;
+ MSIFEATURE *feature;
+ UINT ret;
+
+ TRACE("(%d %s %i %i %p)\n", hInstall, debugstr_w(szFeature),
iCostTree, iState, piCost);
- if (piCost) *piCost = 0;
+
+ package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
+ if (!package)
+ {
+ HRESULT hr;
+ BSTR feature;
+ IWineMsiRemotePackage *remote_package;
+
+ remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
+ if (!remote_package)
+ return ERROR_INVALID_HANDLE;
+
+ feature = SysAllocString(szFeature);
+ if (!feature)
+ {
+ IWineMsiRemotePackage_Release(remote_package);
+ return ERROR_OUTOFMEMORY;
+ }
+
+ hr = IWineMsiRemotePackage_GetFeatureCost(remote_package, feature,
+ iCostTree, iState, piCost);
+
+ SysFreeString(feature);
+ IWineMsiRemotePackage_Release(remote_package);
+
+ if (FAILED(hr))
+ {
+ if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
+ return HRESULT_CODE(hr);
+
+ return ERROR_FUNCTION_FAILED;
+ }
+
- return ERROR_SUCCESS;
- }
+ return ERROR_SUCCESS;
+}
+ feature = get_loaded_feature(package, szFeature);
+
+ if (feature)
+ ret = MSI_GetFeatureCost(package, feature, iCostTree, iState, piCost);
+ else
+ ret = ERROR_UNKNOWN_FEATURE;
+
+ msiobj_release( &package->hdr );
+ return ret;
+ }
+
/***********************************************************************
* MsiSetComponentStateA (MSI.@)
*/
gUIHandlerA(gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, msg);
msi_free(msg);
}
- }
+ else if (gUIHandlerRecord)
+ {
+ MSIHANDLE rec = MsiCreateRecord(1);
+ MsiRecordSetStringW(rec, 0, error);
+ gUIHandlerRecord(gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, rec);
+ MsiCloseHandle(rec);
++ }
}
msi_free(error);
{
INSTALLUI_HANDLERA prev = gUIHandlerA;
- TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext);
+ TRACE("%p %08x %p\n", puiHandler, dwMessageFilter, pvContext);
+
gUIHandlerA = puiHandler;
- gUIFilter = dwMessageFilter;
- gUIContext = pvContext;
+ gUIHandlerW = NULL;
+ gUIFilter = dwMessageFilter;
+ gUIContext = pvContext;
return prev;
}
{
INSTALLUI_HANDLERW prev = gUIHandlerW;
- TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext);
+ TRACE("%p %08x %p\n", puiHandler, dwMessageFilter, pvContext);
+
+ gUIHandlerA = NULL;
gUIHandlerW = puiHandler;
- gUIFilter = dwMessageFilter;
- gUIContext = pvContext;
+ gUIFilter = dwMessageFilter;
+ gUIContext = pvContext;
return prev;
}
static LONG dll_count;
/* the UI level */
-INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
-HWND gUIhwnd = 0;
-INSTALLUI_HANDLERA gUIHandlerA = NULL;
-INSTALLUI_HANDLERW gUIHandlerW = NULL;
+INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
+HWND gUIhwnd = 0;
+INSTALLUI_HANDLERA gUIHandlerA = NULL;
+INSTALLUI_HANDLERW gUIHandlerW = NULL;
+ INSTALLUI_HANDLER_RECORD gUIHandlerRecord = NULL;
-DWORD gUIFilter = 0;
-LPVOID gUIContext = NULL;
+DWORD gUIFilter = 0;
+LPVOID gUIContext = NULL;
WCHAR gszLogFile[MAX_PATH];
HINSTANCE msi_hInstance;
}
}
- TRACE("(%p %x %x %s)\n", gUIHandlerA, gUIFilter, log_type,
- debugstr_w(message));
+ TRACE("%p %p %p %x %x %s\n", gUIHandlerA, gUIHandlerW, gUIHandlerRecord,
+ gUIFilter, log_type, debugstr_w(message));
/* convert it to ASCII */
- len = WideCharToMultiByte( CP_ACP, 0, message, -1,
- NULL, 0, NULL, NULL );
+ len = WideCharToMultiByte( CP_ACP, 0, message, -1, NULL, 0, NULL, NULL );
msg = msi_alloc( len );
- WideCharToMultiByte( CP_ACP, 0, message, -1,
- msg, len, NULL, NULL );
+ WideCharToMultiByte( CP_ACP, 0, message, -1, msg, len, NULL, NULL );
- if (gUIHandlerA && (gUIFilter & log_type))
+ if (gUIHandlerW && (gUIFilter & log_type))
+ {
+ rc = gUIHandlerW( gUIContext, eMessageType, message );
+ }
+ else if (gUIHandlerA && (gUIFilter & log_type))
{
- rc = gUIHandlerA( gUIContext, eMessageType, msg );
+ rc = gUIHandlerA(gUIContext,eMessageType,msg);
}
+ else if (gUIHandlerRecord && (gUIFilter & log_type))
+ {
+ MSIHANDLE rec = MsiCreateRecord( 1 );
+ MsiRecordSetStringW( rec, 0, message );
+ rc = gUIHandlerRecord( gUIContext, eMessageType, rec );
+ MsiCloseHandle( rec );
+ }
if ((!rc) && (gszLogFile[0]) && !((eMessageType & 0xff000000) ==
INSTALLMESSAGE_PROGRESS))
}
}
msi_free( msg );
-
- msi_free( message );
+ msi_free( message);
switch (eMessageType & 0xff000000)
{
- <module name="msvcrt" type="win32dll" baseaddress="${BASEADDRESS_MSVCRT}" mangledsymbols="true" installbase="system32" installname="msvcrt.dll" iscrt="yes">
+ <module name="msvcrt" type="win32dll" baseaddress="${BASEADDRESS_MSVCRT}" installbase="system32" installname="msvcrt.dll" iscrt="yes">
- <importlibrary definition="msvcrt.def" />
+ <importlibrary definition="msvcrt-$(ARCH).def" />
<include base="msvcrt">.</include>
<include base="crt">include</include>
<define name="USE_MSVCRT_PREFIX" />
<module name="nddeapi" type="win32dll" baseaddress="${BASEADDRESS_NDDEAPI}" installbase="system32" installname="nddeapi.dll" allowwarnings="true" entrypoint="0">
- <importlibrary definition="nddeapi.spec" />
- <include base="nddeapi">.</include>
- <include base="ReactOS">include/reactos/wine</include>
- <define name="__WINESRC__" />
- <library>wine</library>
- <library>ntdll</library>
- <file>nddeapi.c</file>
+ <importlibrary definition="nddeapi.spec" />
+ <include base="nddeapi">.</include>
+ <include base="ReactOS">include/reactos/wine</include>
+ <define name="__WINESRC__" />
+ <library>wine</library>
- <library>kernel32</library>
+ <library>ntdll</library>
+ <file>nddeapi.c</file>
</module>
<module name="ntdsapi" type="win32dll" baseaddress="${BASEADDRESS_NTDSAPI}" installbase="system32" installname="ntdsapi.dll" allowwarnings="true" entrypoint="0">
- <importlibrary definition="ntdsapi.spec" />
- <include base="ntdsapi">.</include>
- <include base="ReactOS">include/reactos/wine</include>
- <define name="__WINESRC__" />
- <library>wine</library>
- <library>user32</library>
- <library>ntdll</library>
- <file>ntdsapi.c</file>
+ <importlibrary definition="ntdsapi.spec" />
+ <include base="ntdsapi">.</include>
+ <include base="ReactOS">include/reactos/wine</include>
+ <define name="__WINESRC__" />
+ <library>wine</library>
+ <library>user32</library>
- <library>kernel32</library>
+ <library>ntdll</library>
+ <file>ntdsapi.c</file>
</module>
<include base="ReactOS">include/reactos/wine</include>
<define name="__WINESRC__" />
<library>wine</library>
- <library>advapi32</library>
- <library>kernel32</library>
<file>proxyodbc.c</file>
</module>
--</group>
++</group>
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
- <group>
<module name="olecli32" type="win32dll" baseaddress="${BASEADDRESS_OLECLI32}" installbase="system32" installname="olecli32.dll" allowwarnings="true" entrypoint="0">
- <importlibrary definition="olecli32.spec" />
- <include base="olecli32">.</include>
- <include base="ReactOS">include/reactos/wine</include>
- <define name="__WINESRC__" />
- <file>olecli_main.c</file>
- <library>wine</library>
- <library>ole32</library>
- <library>gdi32</library>
- <library>ntdll</library>
+ <importlibrary definition="olecli32.spec" />
+ <include base="olecli32">.</include>
+ <include base="ReactOS">include/reactos/wine</include>
+ <define name="__WINESRC__" />
+ <file>olecli_main.c</file>
+ <library>wine</library>
+ <library>ole32</library>
+ <library>gdi32</library>
- <library>kernel32</library>
+ <library>ntdll</library>
</module>
- </group>
<module name="pdh" type="win32dll" baseaddress="${BASEADDRESS_PDH}" installbase="system32" installname="pdh.dll" allowwarnings="true" entrypoint="0">
- <importlibrary definition="pdh.spec" />
- <include base="pdh">.</include>
- <include base="ReactOS">include/reactos/wine</include>
- <define name="__WINESRC__" />
- <redefine name="_WIN32_WINNT">0x600</redefine>
- <library>wine</library>
- <library>ntdll</library>
- <file>pdh_main.c</file>
+ <importlibrary definition="pdh.spec" />
+ <include base="pdh">.</include>
+ <include base="ReactOS">include/reactos/wine</include>
+ <define name="__WINESRC__" />
+ <redefine name="_WIN32_WINNT">0x600</redefine>
+ <library>wine</library>
- <library>kernel32</library>
+ <library>ntdll</library>
+ <file>pdh_main.c</file>
</module>
<module name="printui" type="win32dll" baseaddress="${BASEADDRESS_PRINTUI}" installbase="system32" installname="printui.dll" allowwarnings="true" entrypoint="0">
- <importlibrary definition="printui.spec" />
- <include base="printui">.</include>
- <include base="ReactOS">include/reactos/wine</include>
- <define name="__WINESRC__" />
- <library>wine</library>
- <library>shell32</library>
- <library>ntdll</library>
- <file>printui.c</file>
- <file>printui.rc</file>
+ <importlibrary definition="printui.spec" />
+ <include base="printui">.</include>
+ <include base="ReactOS">include/reactos/wine</include>
+ <define name="__WINESRC__" />
+ <library>wine</library>
+ <library>shell32</library>
- <library>kernel32</library>
+ <library>ntdll</library>
+ <file>printui.c</file>
+ <file>printui.rc</file>
</module>
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE;
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, required ))) return FALSE;
- if (!SetupGetStringFieldA( context, index, buffer, required, NULL )) goto done;
+ if (!(ret = SetupGetStringFieldA( context, index, buffer, required, NULL ))) goto done;
}
- res = strtol( buffer, &end, 0 );
+ /* The call to SetupGetStringFieldA succeeded. If buffer is empty we have an optional field */
+ if (!*buffer) *result = 0;
+ else
+ {
- if (end != buffer && !*end)
+ res = strtol( buffer, &end, 0 );
- {
+ if (end != buffer && !*end) *result = res;
+ else
- *result = res;
- ret = TRUE;
+ {
- }
+ SetLastError( ERROR_INVALID_DATA );
+ ret = FALSE;
++ }
}
- else SetLastError( ERROR_INVALID_DATA );
done:
if (buffer != localbuff) HeapFree( GetProcessHeap(), 0, buffer );
}
--BOOL
++INT_PTR
CALLBACK
FormatDriveDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
{
psfi->dwAttributes = 0xffffffff;
}
- IShellFolder_GetAttributesOf( psfParent, 1, (LPCITEMIDLIST*)&pidlLast,
+ if (psfParent)
+ IShellFolder_GetAttributesOf( psfParent, 1, (LPCITEMIDLIST*)&pidlLast,
&(psfi->dwAttributes) );
}
GetSystemMetrics( SM_CXICON),
GetSystemMetrics( SM_CYICON),
&psfi->hIcon, 0, 1, 0);
- psfi->iIcon = icon_idx;
- }
+ if (ret != 0 && ret != 0xFFFFFFFF)
+ {
+ IconNotYetLoaded=FALSE;
+ psfi->iIcon = icon_idx;
}
}
}
}
++ }
else
{
if (!(PidlToSicIndex(psfParent, pidlLast, !(flags & SHGFI_SMALLICON),
return 0x80041001;
}
- /* found scheme, set length of remainder */
- y->cchSuffix = lstrlenA(y->pszSuffix);
+ y->pszProtocol = x;
+ y->cchProtocol = ptr-x;
+ y->pszSuffix = ptr+1;
+ y->cchSuffix = strlen(y->pszSuffix);
- len = MultiByteToWideChar(CP_ACP, 0, y->pszProtocol, y->cchProtocol,
+ len = MultiByteToWideChar(CP_ACP, 0, x, ptr-x,
- scheme, sizeof(scheme)/sizeof(WCHAR));
+ scheme, sizeof(scheme)/sizeof(WCHAR));
y->nScheme = get_scheme_code(scheme, len);
return S_OK;
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
- <group>
<module name="sxs" type="win32dll" baseaddress="${BASEADDRESS_SXS}" installbase="system32" installname="sxs.dll" allowwarnings="true" entrypoint="0">
- <importlibrary definition="sxs.spec" />
- <include base="sxs">.</include>
- <include base="ReactOS">include/reactos/wine</include>
- <define name="__WINESRC__" />
- <file>sxs.c</file>
- <library>wine</library>
- <library>ntdll</library>
+ <importlibrary definition="sxs.spec" />
+ <include base="sxs">.</include>
+ <include base="ReactOS">include/reactos/wine</include>
+ <define name="__WINESRC__" />
+ <file>sxs.c</file>
+ <library>wine</library>
- <library>kernel32</library>
+ <library>ntdll</library>
</module>
- </group>
}
else /* Not a popup */
{
- if (*str == 0)
- flags = MF_SEPARATOR;
+ if(!unicode)
+ {
+ if (*str == 0)
+ flags = MF_SEPARATOR;
+ }
+ else
+ {
+ if (*(LPCWSTR)str == 0)
+ flags = MF_SEPARATOR;
+ }
if (flags & MF_SEPARATOR)
{
<module name="winfax" type="win32dll" baseaddress="${BASEADDRESS_WINFAX}" installbase="system32" installname="winfax.dll" allowwarnings="true" entrypoint="0">
- <importlibrary definition="winfax.spec" />
- <include base="winfax">.</include>
- <library>ntdll</library>
- <file>winfax.c</file>
- <file>winfax.rc</file>
+ <importlibrary definition="winfax.spec" />
+ <include base="winfax">.</include>
- <library>kernel32</library>
+ <library>ntdll</library>
+ <file>winfax.c</file>
+ <file>winfax.rc</file>
- </module>
+ </module>
UrlComponents.dwHostNameLength = hostNameLen;
UrlComponents.dwUrlPathLength = pathLen;
- rc = InternetCrackUrlW(lpszUrl, 0, 0, &UrlComponents);
-
- /* discard the webpage off the end of the path */
- if (pathLen > 0 && path[pathLen-1] != '/')
- {
- LPWSTR ptr;
- ptr = strrchrW(path,'/');
- if (ptr)
- *(++ptr) = 0;
- else
- {
- path[0] = '/';
- path[1] = 0;
+ return InternetCrackUrlW(lpszUrl, 0, 0, &UrlComponents);
-}
+ }
- }
- return rc;
- }
/* match a domain. domain must match if the domain is not NULL. path must match if the path is not NULL */
static BOOL COOKIE_matchDomain(LPCWSTR lpszCookieDomain, LPCWSTR lpszCookiePath,
}
if (lpszCookiePath)
{
- INT len;
TRACE("comparing paths: %s with %s\n", debugstr_w(lpszCookiePath), debugstr_w(searchDomain->lpCookiePath));
- /* paths match at the beginning. so a path of /foo would match
- * /foobar and /foo/bar
- */
if (!searchDomain->lpCookiePath)
return FALSE;
- if (allow_partial)
- {
- len = lstrlenW(searchDomain->lpCookiePath);
- if (strncmpiW(searchDomain->lpCookiePath, lpszCookiePath, len)!=0)
+ if (strcmpW(lpszCookiePath, searchDomain->lpCookiePath))
- return FALSE;
- }
+ return FALSE;
+ }
- else if (strcmpW(lpszCookiePath, searchDomain->lpCookiePath))
- return FALSE;
-
- }
return TRUE;
}
}
if (!thisCookieDomain)
- {
- if (!expired)
- thisCookieDomain = COOKIE_addDomain(domain, path);
+ thisCookieDomain = COOKIE_addDomain(domain, path);
- else
- {
- HeapFree(GetProcessHeap(),0,data);
- if (value != data) HeapFree(GetProcessHeap(), 0, value);
- return TRUE;
- }
- }
if ((thisCookie = COOKIE_findCookie(thisCookieDomain, cookie_name)))
COOKIE_deleteCookie(thisCookie, FALSE);
*/
static BOOL WININET_GetProxyServer( HINTERNET hRequest, LPWSTR szBuf, DWORD sz )
{
- http_request_t *lpwhr;
- http_session_t *lpwhs = NULL;
- appinfo_t *hIC = NULL;
- BOOL ret = FALSE;
+ LPWININETHTTPREQW lpwhr;
+ LPWININETHTTPSESSIONW lpwhs = NULL;
+ LPWININETAPPINFOW hIC = NULL;
LPWSTR p;
- lpwhr = (http_request_t*) WININET_GetObject( hRequest );
+ lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hRequest );
if (NULL == lpwhr)
- return FALSE;
+ return FALSE;
lpwhs = lpwhr->lpHttpSession;
if (NULL == lpwhs)
}
/***********************************************************************
- * WININET_SetAuthorization
+ * WININET_SetProxyAuthorization
*/
- static BOOL WININET_SetAuthorization( HINTERNET hRequest, LPWSTR username,
- LPWSTR password, BOOL proxy )
+ static BOOL WININET_SetProxyAuthorization( HINTERNET hRequest,
+ LPWSTR username, LPWSTR password )
{
- http_request_t *lpwhr;
- http_session_t *lpwhs;
- BOOL ret = FALSE;
- LPWSTR p, q;
+ LPWININETHTTPREQW lpwhr;
+ LPWININETHTTPSESSIONW lpwhs;
+ LPWININETAPPINFOW hIC;
+ LPWSTR p;
- lpwhr = (http_request_t*) WININET_GetObject( hRequest );
+ lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hRequest );
if( !lpwhr )
- return FALSE;
-
+ return FALSE;
+
lpwhs = lpwhr->lpHttpSession;
if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION)
{
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
- goto done;
+ return FALSE;
}
- p = heap_strdupW(username);
- if( !p )
- goto done;
-
- q = heap_strdupW(password);
- if( !q )
- {
- HeapFree(GetProcessHeap(), 0, username);
- goto done;
- }
+ hIC = lpwhs->lpAppInfo;
- if (proxy)
- {
- appinfo_t *hIC = lpwhs->lpAppInfo;
+ p = HeapAlloc( GetProcessHeap(), 0, (strlenW( username ) + 1)*sizeof(WCHAR) );
+ if( !p )
+ return FALSE;
-
+
- HeapFree(GetProcessHeap(), 0, hIC->lpszProxyUsername);
+ lstrcpyW( p, username );
- hIC->lpszProxyUsername = p;
+ hIC->lpszProxyUsername = p;
- HeapFree(GetProcessHeap(), 0, hIC->lpszProxyPassword);
- hIC->lpszProxyPassword = q;
- }
- else
- {
- HeapFree(GetProcessHeap(), 0, lpwhs->lpszUserName);
- lpwhs->lpszUserName = p;
-
- HeapFree(GetProcessHeap(), 0, lpwhs->lpszPassword);
- lpwhs->lpszPassword = q;
- }
+ p = HeapAlloc( GetProcessHeap(), 0, (strlenW( password ) + 1)*sizeof(WCHAR) );
+ if( !p )
+ return FALSE;
-
+
- ret = TRUE;
+ lstrcpyW( p, password );
+ hIC->lpszProxyPassword = p;
- done:
- WININET_Release( &lpwhr->hdr );
- return ret;
+ return TRUE;
}
/***********************************************************************
switch( dwError )
{
case ERROR_SUCCESS:
- case ERROR_INTERNET_INCORRECT_PASSWORD:
- if( !dwError && !(dwFlags & FLAGS_ERROR_UI_FILTER_FOR_ERRORS ) )
+ if( !(dwFlags & FLAGS_ERROR_UI_FILTER_FOR_ERRORS ) )
return 0;
-
dwStatus = WININET_GetConnectionStatus( hRequest );
- switch (dwStatus)
- {
- case HTTP_STATUS_PROXY_AUTH_REQ:
+ if( HTTP_STATUS_PROXY_AUTH_REQ != dwStatus )
+ return ERROR_SUCCESS;
- return DialogBoxParamW( hwininet, MAKEINTRESOURCEW( IDD_PROXYDLG ),
- hWnd, WININET_ProxyPasswordDialog, (LPARAM) ¶ms );
+ return DialogBoxParamW( hwininet, MAKEINTRESOURCEW( IDD_PROXYDLG ),
+ hWnd, WININET_ProxyPasswordDialog, (LPARAM) ¶ms );
- case HTTP_STATUS_DENIED:
- return DialogBoxParamW( hwininet, MAKEINTRESOURCEW( IDD_AUTHDLG ),
- hWnd, WININET_PasswordDialog, (LPARAM) ¶ms );
- default:
- WARN("unhandled status %u\n", dwStatus);
- return 0;
- }
+
+ case ERROR_INTERNET_INCORRECT_PASSWORD:
+ return DialogBoxParamW( hwininet, MAKEINTRESOURCEW( IDD_PROXYDLG ),
+ hWnd, WININET_ProxyPasswordDialog, (LPARAM) ¶ms );
case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
case ERROR_INTERNET_INVALID_CA:
return bSuccess;
}
-
+ /***********************************************************************
+ * FtpOpenFileA (WININET.@)
+ *
+ * Open a remote file for writing or reading
+ *
+ * RETURNS
+ * HINTERNET handle on success
+ * NULL on failure
+ *
+ */
+ HINTERNET WINAPI FtpOpenFileA(HINTERNET hFtpSession,
+ LPCSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
+ DWORD_PTR dwContext)
+ {
+ LPWSTR lpwzFileName;
+ HINTERNET ret;
++
+ lpwzFileName = lpszFileName?WININET_strdup_AtoW(lpszFileName):NULL;
+ ret = FtpOpenFileW(hFtpSession, lpwzFileName, fdwAccess, dwFlags, dwContext);
+ HeapFree(GetProcessHeap(), 0, lpwzFileName);
+ return ret;
+ }
+
+
+ static void AsyncFtpOpenFileProc(WORKREQUEST *workRequest)
+ {
+ struct WORKREQ_FTPOPENFILEW const *req = &workRequest->u.FtpOpenFileW;
+ LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr;
+
+ TRACE("%p\n", lpwfs);
+
+ FTP_FtpOpenFileW(lpwfs, req->lpszFilename,
+ req->dwAccess, req->dwFlags, req->dwContext);
+ HeapFree(GetProcessHeap(), 0, req->lpszFilename);
+ }
+
+ /***********************************************************************
+ * FtpOpenFileW (WININET.@)
+ *
+ * Open a remote file for writing or reading
+ *
+ * RETURNS
+ * HINTERNET handle on success
+ * NULL on failure
+ *
+ */
+ HINTERNET WINAPI FtpOpenFileW(HINTERNET hFtpSession,
+ LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
+ DWORD_PTR dwContext)
+ {
+ LPWININETFTPSESSIONW lpwfs;
+ LPWININETAPPINFOW hIC = NULL;
+ HINTERNET r = NULL;
+
+ TRACE("(%p,%s,0x%08x,0x%08x,0x%08lx)\n", hFtpSession,
+ debugstr_w(lpszFileName), fdwAccess, dwFlags, dwContext);
+
+ lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession );
+ if (!lpwfs)
+ {
+ INTERNET_SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (WH_HFTPSESSION != lpwfs->hdr.htype)
+ {
+ INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
+ goto lend;
+ }
+
+ if ((!lpszFileName) ||
+ ((fdwAccess != GENERIC_READ) && (fdwAccess != GENERIC_WRITE)) ||
+ ((dwFlags & FTP_CONDITION_MASK) > FTP_TRANSFER_TYPE_BINARY))
+ {
+ INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
+ goto lend;
+ }
+
+ if (lpwfs->download_in_progress != NULL)
+ {
+ INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS);
+ goto lend;
+ }
+
+ hIC = lpwfs->lpAppInfo;
+ if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
+ {
+ WORKREQUEST workRequest;
+ struct WORKREQ_FTPOPENFILEW *req;
+
+ workRequest.asyncproc = AsyncFtpOpenFileProc;
+ workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
+ req = &workRequest.u.FtpOpenFileW;
+ req->lpszFilename = WININET_strdupW(lpszFileName);
+ req->dwAccess = fdwAccess;
+ req->dwFlags = dwFlags;
+ req->dwContext = dwContext;
+
+ INTERNET_AsyncCall(&workRequest);
+ r = NULL;
+ }
+ else
+ {
+ r = FTP_FtpOpenFileW(lpwfs, lpszFileName, fdwAccess, dwFlags, dwContext);
+ }
+
+ lend:
+ WININET_Release( &lpwfs->hdr );
+
+ return r;
+ }
+
/***********************************************************************
* FTPFILE_Destroy(internal)
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
- if(bSuccess) {
- FTP_ReceiveRequestData(lpwh, TRUE);
- }else {
- iar.dwResult = 0;
- iar.dwError = INTERNET_GetLastError();
+ iar.dwResult = (DWORD)bSuccess;
+ iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
- SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
- &iar, sizeof(INTERNET_ASYNC_RESULT));
- }
+ SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
+ &iar, sizeof(INTERNET_ASYNC_RESULT));
+ }
- }
lend:
if( lpwh )
05-09-03 06:02PM 12656686 2003-04-21bgm_cmd_e.rgz
*/
else if(isdigit(pszToken[0]) && 8 == strlen(pszToken)) {
- int mon, mday, year, hour, min;
lpfp->permissions = 0xFFFF; /* No idea, put full permission :-) */
- sscanf(pszToken, "%d-%d-%d", &mon, &mday, &year);
- lpfp->tmLastModified.wDay = mday;
- lpfp->tmLastModified.wMonth = mon;
- lpfp->tmLastModified.wYear = year;
+ sscanf(pszToken, "%d-%d-%d",
+ &lpfp->tmLastModified.tm_mon,
+ &lpfp->tmLastModified.tm_mday,
+ &lpfp->tmLastModified.tm_year);
/* Hacky and bad Y2K protection :-) */
- if (lpfp->tmLastModified.wYear < 70) lpfp->tmLastModified.wYear += 2000;
+ if (lpfp->tmLastModified.tm_year < 70)
+ lpfp->tmLastModified.tm_year += 100;
-
+
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;
- sscanf(pszToken, "%d:%d", &hour, &min);
- lpfp->tmLastModified.wHour = hour;
- lpfp->tmLastModified.wMinute = min;
+ sscanf(pszToken, "%d:%d",
+ &lpfp->tmLastModified.tm_hour,
+ &lpfp->tmLastModified.tm_min);
if((pszToken[5] == 'P') && (pszToken[6] == 'M')) {
- lpfp->tmLastModified.wHour += 12;
+ lpfp->tmLastModified.tm_hour += 12;
}
- lpfp->tmLastModified.wSecond = 0;
+ lpfp->tmLastModified.tm_sec = 0;
- TRACE("Mod time: %02d:%02d:%02d %04d/%02d/%02d\n",
- lpfp->tmLastModified.wHour, lpfp->tmLastModified.wMinute, lpfp->tmLastModified.wSecond,
- lpfp->tmLastModified.wYear, lpfp->tmLastModified.wMonth, lpfp->tmLastModified.wDay);
+ TRACE("Mod time: %02d:%02d:%02d %02d/%02d/%02d\n",
+ lpfp->tmLastModified.tm_hour, lpfp->tmLastModified.tm_min, lpfp->tmLastModified.tm_sec,
+ (lpfp->tmLastModified.tm_year >= 100) ? lpfp->tmLastModified.tm_year - 100 : lpfp->tmLastModified.tm_year,
+ lpfp->tmLastModified.tm_mon, lpfp->tmLastModified.tm_mday);
-
+
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;
if(!strcasecmp(pszToken, "<DIR>")) {
int i;
LPCWSTR next_token;
- if (string)
- {
- /* empty string has no tokens */
- if (*string)
- tokens++;
- /* count tokens */
- for (i = 0; string[i]; i++)
- if (!strncmpW(string+i, token_string, strlenW(token_string)))
- {
- DWORD j;
+ /* empty string has no tokens */
+ if (*string)
tokens++;
- /* we want to skip over separators, but not the null terminator */
- for (j = 0; j < strlenW(token_string) - 1; j++)
- if (!string[i+j])
- break;
- i += j;
- }
+ /* count tokens */
+ for (i = 0; string[i]; i++)
- {
+ if (!strncmpW(string+i, token_string, strlenW(token_string)))
+ {
+ DWORD j;
+ tokens++;
+ /* we want to skip over separators, but not the null terminator */
+ for (j = 0; j < strlenW(token_string) - 1; j++)
+ if (!string[i+j])
+ break;
+ i += j;
+ }
- }
- }
/* add 1 for terminating NULL */
token_array = HeapAlloc(GetProcessHeap(), 0, (tokens+1) * sizeof(*token_array));
return requestString;
}
- static void HTTP_ProcessCookies( http_request_t *lpwhr )
+ static void HTTP_ProcessCookies( LPWININETHTTPREQW lpwhr )
{
+ static const WCHAR szSet_Cookie[] = { 'S','e','t','-','C','o','o','k','i','e',0 };
int HeaderIndex;
- int numCookies = 0;
LPHTTPHEADERW setCookieHeader;
- while((HeaderIndex = HTTP_GetCustomHeaderIndex(lpwhr, szSet_Cookie, numCookies, FALSE)) != -1)
- {
+ HeaderIndex = HTTP_GetCustomHeaderIndex(lpwhr, szSet_Cookie, 0, FALSE);
+ if (HeaderIndex == -1)
+ return;
- setCookieHeader = &lpwhr->pCustHeaders[HeaderIndex];
+ setCookieHeader = &lpwhr->pCustHeaders[HeaderIndex];
- if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_COOKIES) && setCookieHeader->lpszValue)
- {
+ if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_COOKIES) && setCookieHeader->lpszValue)
+ {
- int len;
- static const WCHAR szFmt[] = { 'h','t','t','p',':','/','/','%','s','%','s',0};
+ int nPosStart = 0, nPosEnd = 0, len;
+ static const WCHAR szFmt[] = { 'h','t','t','p',':','/','/','%','s','/',0};
+
+ while (setCookieHeader->lpszValue[nPosEnd] != '\0')
+ {
+ LPWSTR buf_cookie, cookie_name, cookie_data;
LPWSTR buf_url;
+ LPWSTR domain = NULL;
LPHTTPHEADERW Host;
- Host = HTTP_GetHeader(lpwhr, hostW);
- len = lstrlenW(Host->lpszValue) + 9 + lstrlenW(lpwhr->lpszPath);
- buf_url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
- sprintfW(buf_url, szFmt, Host->lpszValue, lpwhr->lpszPath);
- InternetSetCookieW(buf_url, NULL, setCookieHeader->lpszValue);
-
- HeapFree(GetProcessHeap(), 0, buf_url);
- }
- numCookies++;
- }
- }
-
- static void strip_spaces(LPWSTR start)
+ int nEqualPos = 0;
+ while (setCookieHeader->lpszValue[nPosEnd] != ';' && setCookieHeader->lpszValue[nPosEnd] != ',' &&
+ setCookieHeader->lpszValue[nPosEnd] != '\0')
- {
+{
- LPWSTR str = start;
- LPWSTR end;
-
- while (*str == ' ' && *str != '\0')
- str++;
-
- if (str != start)
- memmove(start, str, sizeof(WCHAR) * (strlenW(str) + 1));
-
- end = start + strlenW(start) - 1;
- while (end >= start && *end == ' ')
- {
- *end = '\0';
- end--;
+ nPosEnd++;
- }
+ }
- }
-
- static inline BOOL is_basic_auth_value( LPCWSTR pszAuthValue, LPWSTR *pszRealm )
+ if (setCookieHeader->lpszValue[nPosEnd] == ';')
- {
+{
- static const WCHAR szBasic[] = {'B','a','s','i','c'}; /* Note: not nul-terminated */
- static const WCHAR szRealm[] = {'r','e','a','l','m'}; /* Note: not nul-terminated */
- BOOL is_basic;
- is_basic = !strncmpiW(pszAuthValue, szBasic, ARRAYSIZE(szBasic)) &&
- ((pszAuthValue[ARRAYSIZE(szBasic)] == ' ') || !pszAuthValue[ARRAYSIZE(szBasic)]);
- if (is_basic && pszRealm)
+ /* fixme: not case sensitive, strcasestr is gnu only */
+ int nDomainPosEnd = 0;
+ int nDomainPosStart = 0, nDomainLength = 0;
+ static const WCHAR szDomain[] = {'d','o','m','a','i','n','=',0};
+ LPWSTR lpszDomain = strstrW(&setCookieHeader->lpszValue[nPosEnd], szDomain);
+ if (lpszDomain)
+ { /* they have specified their own domain, lets use it */
+ while (lpszDomain[nDomainPosEnd] != ';' && lpszDomain[nDomainPosEnd] != ',' &&
+ lpszDomain[nDomainPosEnd] != '\0')
- {
+ {
- LPCWSTR token;
- LPCWSTR ptr = &pszAuthValue[ARRAYSIZE(szBasic)];
- LPCWSTR realm;
- ptr++;
- *pszRealm=NULL;
- token = strchrW(ptr,'=');
- if (!token)
- return TRUE;
- realm = ptr;
- while (*realm == ' ' && *realm != '\0')
- realm++;
- if(!strncmpiW(realm, szRealm, ARRAYSIZE(szRealm)) &&
- (realm[ARRAYSIZE(szRealm)] == ' ' || realm[ARRAYSIZE(szRealm)] == '='))
- {
- token++;
- while (*token == ' ' && *token != '\0')
- token++;
- if (*token == '\0')
- return TRUE;
- *pszRealm = heap_strdupW(token);
- strip_spaces(*pszRealm);
+ nDomainPosEnd++;
- }
+ }
+ nDomainPosStart = strlenW(szDomain);
+ nDomainLength = (nDomainPosEnd - nDomainPosStart) + 1;
+ domain = HeapAlloc(GetProcessHeap(), 0, (nDomainLength + 1)*sizeof(WCHAR));
+ lstrcpynW(domain, &lpszDomain[nDomainPosStart], nDomainLength + 1);
- }
- }
+ }
-
- return is_basic;
+}
-
- static void destroy_authinfo( struct HttpAuthInfo *authinfo )
+ if (setCookieHeader->lpszValue[nPosEnd] == '\0') break;
+ buf_cookie = HeapAlloc(GetProcessHeap(), 0, ((nPosEnd - nPosStart) + 1)*sizeof(WCHAR));
+ lstrcpynW(buf_cookie, &setCookieHeader->lpszValue[nPosStart], (nPosEnd - nPosStart) + 1);
+ TRACE("%s\n", debugstr_w(buf_cookie));
+ while (buf_cookie[nEqualPos] != '=' && buf_cookie[nEqualPos] != '\0')
- {
+{
- if (!authinfo) return;
-
- if (SecIsValidHandle(&authinfo->ctx))
- DeleteSecurityContext(&authinfo->ctx);
- if (SecIsValidHandle(&authinfo->cred))
- FreeCredentialsHandle(&authinfo->cred);
-
- HeapFree(GetProcessHeap(), 0, authinfo->auth_data);
- HeapFree(GetProcessHeap(), 0, authinfo->scheme);
- HeapFree(GetProcessHeap(), 0, authinfo);
+ nEqualPos++;
- }
+}
-
- static UINT retrieve_cached_basic_authorization(LPWSTR host, LPWSTR realm, LPSTR *auth_data)
+ if (buf_cookie[nEqualPos] == '\0' || buf_cookie[nEqualPos + 1] == '\0')
- {
+{
- authorizationData *ad;
- UINT rc = 0;
-
- TRACE("Looking for authorization for %s:%s\n",debugstr_w(host),debugstr_w(realm));
-
- EnterCriticalSection(&authcache_cs);
- LIST_FOR_EACH_ENTRY(ad, &basicAuthorizationCache, authorizationData, entry)
- {
- if (!strcmpiW(host,ad->lpszwHost) && !strcmpW(realm,ad->lpszwRealm))
- {
- TRACE("Authorization found in cache\n");
- *auth_data = HeapAlloc(GetProcessHeap(),0,ad->AuthorizationLen);
- memcpy(*auth_data,ad->lpszAuthorization,ad->AuthorizationLen);
- rc = ad->AuthorizationLen;
+ HeapFree(GetProcessHeap(), 0, buf_cookie);
- break;
- }
+ break;
+ }
- }
- LeaveCriticalSection(&authcache_cs);
- return rc;
- }
- static void cache_basic_authorization(LPWSTR host, LPWSTR realm, LPSTR auth_data, UINT auth_data_len)
- {
- struct list *cursor;
- authorizationData* ad = NULL;
+ cookie_name = HeapAlloc(GetProcessHeap(), 0, (nEqualPos + 1)*sizeof(WCHAR));
+ lstrcpynW(cookie_name, buf_cookie, nEqualPos + 1);
+ cookie_data = &buf_cookie[nEqualPos + 1];
- TRACE("caching authorization for %s:%s = %s\n",debugstr_w(host),debugstr_w(realm),debugstr_an(auth_data,auth_data_len));
+ Host = HTTP_GetHeader(lpwhr,szHost);
+ len = lstrlenW((domain ? domain : (Host?Host->lpszValue:NULL))) +
+ strlenW(lpwhr->lpszPath) + 9;
+ buf_url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
+ sprintfW(buf_url, szFmt, (domain ? domain : (Host?Host->lpszValue:NULL))); /* FIXME PATH!!! */
+ InternetSetCookieW(buf_url, cookie_name, cookie_data);
- EnterCriticalSection(&authcache_cs);
- LIST_FOR_EACH(cursor, &basicAuthorizationCache)
- {
- authorizationData *check = LIST_ENTRY(cursor,authorizationData,entry);
- if (!strcmpiW(host,check->lpszwHost) && !strcmpW(realm,check->lpszwRealm))
- {
- ad = check;
- break;
+ HeapFree(GetProcessHeap(), 0, buf_url);
+ HeapFree(GetProcessHeap(), 0, buf_cookie);
+ HeapFree(GetProcessHeap(), 0, cookie_name);
+ HeapFree(GetProcessHeap(), 0, domain);
+ nPosStart = nPosEnd;
}
}
+ }
- if (ad)
+ static inline BOOL is_basic_auth_value( LPCWSTR pszAuthValue )
-{
+ {
- TRACE("Found match in cache, replacing\n");
- HeapFree(GetProcessHeap(),0,ad->lpszAuthorization);
- ad->lpszAuthorization = HeapAlloc(GetProcessHeap(),0,auth_data_len);
- memcpy(ad->lpszAuthorization, auth_data, auth_data_len);
- ad->AuthorizationLen = auth_data_len;
- }
- else
- {
- ad = HeapAlloc(GetProcessHeap(),0,sizeof(authorizationData));
- ad->lpszwHost = heap_strdupW(host);
- ad->lpszwRealm = heap_strdupW(realm);
- ad->lpszAuthorization = HeapAlloc(GetProcessHeap(),0,auth_data_len);
- memcpy(ad->lpszAuthorization, auth_data, auth_data_len);
- ad->AuthorizationLen = auth_data_len;
- list_add_head(&basicAuthorizationCache,&ad->entry);
- TRACE("authorization cached\n");
+ static const WCHAR szBasic[] = {'B','a','s','i','c'}; /* Note: not nul-terminated */
+ return !strncmpiW(pszAuthValue, szBasic, ARRAYSIZE(szBasic)) &&
+ ((pszAuthValue[ARRAYSIZE(szBasic)] == ' ') || !pszAuthValue[ARRAYSIZE(szBasic)]);
-}
+ }
- LeaveCriticalSection(&authcache_cs);
- }
- static BOOL HTTP_DoAuthorization( http_request_t *lpwhr, LPCWSTR pszAuthValue,
+ static BOOL HTTP_DoAuthorization( LPWININETHTTPREQW lpwhr, LPCWSTR pszAuthValue,
struct HttpAuthInfo **ppAuthInfo,
- LPWSTR domain_and_username, LPWSTR password,
- LPWSTR host )
+ LPWSTR domain_and_username, LPWSTR password )
{
SECURITY_STATUS sec_status;
struct HttpAuthInfo *pAuthInfo = *ppAuthInfo;
{
int userlen;
int passlen;
- char *auth_data = NULL;
- UINT auth_data_len = 0;
+ char *auth_data;
- TRACE("basic authentication realm %s\n",debugstr_w(szRealm));
+ TRACE("basic authentication\n");
+
+ /* we don't cache credentials for basic authentication, so we can't
+ * retrieve them if the application didn't pass us any credentials */
+ if (!domain_and_username) return FALSE;
- if (!domain_and_username)
- {
- if (host && szRealm)
- auth_data_len = retrieve_cached_basic_authorization(host, szRealm,&auth_data);
- if (auth_data_len == 0)
- {
- HeapFree(GetProcessHeap(),0,szRealm);
- return FALSE;
- }
- }
- else
- {
- userlen = WideCharToMultiByte(CP_UTF8, 0, domain_and_username, lstrlenW(domain_and_username), NULL, 0, NULL, NULL);
- passlen = WideCharToMultiByte(CP_UTF8, 0, password, lstrlenW(password), NULL, 0, NULL, NULL);
+ userlen = WideCharToMultiByte(CP_UTF8, 0, domain_and_username, lstrlenW(domain_and_username), NULL, 0, NULL, NULL);
+ passlen = WideCharToMultiByte(CP_UTF8, 0, password, lstrlenW(password), NULL, 0, NULL, NULL);
- /* length includes a nul terminator, which will be re-used for the ':' */
- auth_data = HeapAlloc(GetProcessHeap(), 0, userlen + 1 + passlen);
- if (!auth_data)
- return FALSE;
+ /* length includes a nul terminator, which will be re-used for the ':' */
+ auth_data = HeapAlloc(GetProcessHeap(), 0, userlen + 1 + passlen);
+ if (!auth_data)
- {
- HeapFree(GetProcessHeap(),0,szRealm);
+ return FALSE;
- }
- WideCharToMultiByte(CP_UTF8, 0, domain_and_username, -1, auth_data, userlen, NULL, NULL);
- auth_data[userlen] = ':';
- WideCharToMultiByte(CP_UTF8, 0, password, -1, &auth_data[userlen+1], passlen, NULL, NULL);
+ WideCharToMultiByte(CP_UTF8, 0, domain_and_username, -1, auth_data, userlen, NULL, NULL);
+ auth_data[userlen] = ':';
+ WideCharToMultiByte(CP_UTF8, 0, password, -1, &auth_data[userlen+1], passlen, NULL, NULL);
- auth_data_len = userlen + 1 + passlen;
- if (host && szRealm)
- cache_basic_authorization(host, szRealm, auth_data, auth_data_len);
- }
pAuthInfo->auth_data = auth_data;
- pAuthInfo->auth_data_len = auth_data_len;
+ pAuthInfo->auth_data_len = userlen + 1 + passlen;
pAuthInfo->finished = TRUE;
- HeapFree(GetProcessHeap(),0,szRealm);
return TRUE;
}
BOOL WINAPI HttpEndRequestA(HINTERNET hRequest,
LPINTERNET_BUFFERSA lpBuffersOut, DWORD dwFlags, DWORD_PTR dwContext)
{
- TRACE("(%p, %p, %08x, %08lx)\n", hRequest, lpBuffersOut, dwFlags, dwContext);
+ LPINTERNET_BUFFERSA ptr;
+ LPINTERNET_BUFFERSW lpBuffersOutW,ptrW;
+ BOOL rc = FALSE;
- if (lpBuffersOut)
- {
- INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
+ TRACE("(%p, %p, %08x, %08lx): stub\n", hRequest, lpBuffersOut, dwFlags,
+ dwContext);
- return HttpEndRequestW(hRequest, NULL, dwFlags, dwContext);
- }
+ ptr = lpBuffersOut;
+ if (ptr)
+ lpBuffersOutW = (LPINTERNET_BUFFERSW)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY, sizeof(INTERNET_BUFFERSW));
+ else
+ lpBuffersOutW = NULL;
- static BOOL HTTP_HttpEndRequestW(http_request_t *lpwhr, DWORD dwFlags, DWORD_PTR dwContext)
+ ptrW = lpBuffersOutW;
+ while (ptr)
- {
+{
- BOOL rc = FALSE;
- INT responseLen;
- DWORD dwBufferSize;
- INTERNET_ASYNC_RESULT iar;
-
- INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
- INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
+ if (ptr->lpvBuffer && ptr->dwBufferLength)
+ ptrW->lpvBuffer = HeapAlloc(GetProcessHeap(),0,ptr->dwBufferLength);
+ ptrW->dwBufferLength = ptr->dwBufferLength;
+ ptrW->dwBufferTotal= ptr->dwBufferTotal;
- responseLen = HTTP_GetResponseHeaders(lpwhr, TRUE);
- if (responseLen)
- rc = TRUE;
-
- INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
- INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen, sizeof(DWORD));
+ if (ptr->Next)
+ ptrW->Next = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
+ sizeof(INTERNET_BUFFERSW));
- /* process cookies here. Is this right? */
- HTTP_ProcessCookies(lpwhr);
+ ptr = ptr->Next;
+ ptrW = ptrW->Next;
+ }
- if (!set_content_length( lpwhr )) HTTP_FinishedReading(lpwhr);
+ rc = HttpEndRequestW(hRequest, lpBuffersOutW, dwFlags, dwContext);
- if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT))
+ if (lpBuffersOutW)
{
- DWORD dwCode,dwCodeLength = sizeof(DWORD);
- if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE, &dwCode, &dwCodeLength, NULL) &&
- (dwCode == 302 || dwCode == 301 || dwCode == 303))
+ ptrW = lpBuffersOutW;
+ while (ptrW)
{
- WCHAR *new_url, szNewLocation[INTERNET_MAX_URL_LENGTH];
- dwBufferSize=sizeof(szNewLocation);
- if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_LOCATION, szNewLocation, &dwBufferSize, NULL))
- {
- if (strcmpW(lpwhr->lpszVerb, szGET) && strcmpW(lpwhr->lpszVerb, szHEAD))
- {
- HeapFree(GetProcessHeap(), 0, lpwhr->lpszVerb);
- lpwhr->lpszVerb = heap_strdupW(szGET);
+ LPINTERNET_BUFFERSW ptrW2;
+
+ FIXME("Do we need to translate info out of these buffer?\n");
+
+ HeapFree(GetProcessHeap(),0,ptrW->lpvBuffer);
+ ptrW2 = ptrW->Next;
+ HeapFree(GetProcessHeap(),0,ptrW);
+ ptrW = ptrW2;
- }
- }
+ }
- HTTP_DrainContent(lpwhr);
- if ((new_url = HTTP_GetRedirectURL( lpwhr, szNewLocation )))
- {
- INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_REDIRECT,
- new_url, (strlenW(new_url) + 1) * sizeof(WCHAR));
- rc = HTTP_HandleRedirect(lpwhr, new_url);
- if (rc)
- rc = HTTP_HttpSendRequestW(lpwhr, NULL, 0, NULL, 0, 0, TRUE);
- HeapFree( GetProcessHeap(), 0, new_url );
+ }
- }
- }
- }
-
- iar.dwResult = (DWORD_PTR)lpwhr->hdr.hInternet;
- iar.dwError = rc ? 0 : INTERNET_GetLastError();
- INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
- INTERNET_STATUS_REQUEST_COMPLETE, &iar,
- sizeof(INTERNET_ASYNC_RESULT));
return rc;
}
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
if (lpwhr)
WININET_Release( &lpwhr->hdr );
- return FALSE;
+ return FALSE;
}
+
lpwhr->hdr.dwFlags |= dwFlags;
+ lpwhr->hdr.dwContext = dwContext;
- if (lpwhr->lpHttpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC)
- {
- WORKREQUEST work;
- struct WORKREQ_HTTPENDREQUESTW *request;
+ /* We appear to do nothing with lpBuffersOut.. is that correct? */
- work.asyncproc = AsyncHttpEndRequestProc;
- work.hdr = WININET_AddRef( &lpwhr->hdr );
+ SendAsyncCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
+
+ responseLen = HTTP_GetResponseHeaders(lpwhr, TRUE);
+ if (responseLen)
+ rc = TRUE;
- request = &work.u.HttpEndRequestW;
- request->dwFlags = dwFlags;
- request->dwContext = dwContext;
+ SendAsyncCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen, sizeof(DWORD));
- INTERNET_AsyncCall(&work);
- INTERNET_SetLastError(ERROR_IO_PENDING);
+ /* process cookies here. Is this right? */
+ HTTP_ProcessCookies(lpwhr);
+
+ dwBufferSize = sizeof(lpwhr->dwContentLength);
+ if (!HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,
+ &lpwhr->dwContentLength,&dwBufferSize,NULL))
+ lpwhr->dwContentLength = -1;
+
+ if (lpwhr->dwContentLength == 0)
+ HTTP_FinishedReading(lpwhr);
+
+ if(!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT))
+ {
+ DWORD dwCode,dwCodeLength=sizeof(DWORD);
+ if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,NULL) &&
+ (dwCode==302 || dwCode==301))
+ {
+ WCHAR szNewLocation[INTERNET_MAX_URL_LENGTH];
+ dwBufferSize=sizeof(szNewLocation);
+ if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,NULL))
+ {
+ /* redirects are always GETs */
+ HeapFree(GetProcessHeap(),0,lpwhr->lpszVerb);
+ lpwhr->lpszVerb = WININET_strdupW(szGET);
+ HTTP_DrainContent(lpwhr);
+ INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_REDIRECT, szNewLocation,
+ dwBufferSize);
+ rc = HTTP_HandleRedirect(lpwhr, szNewLocation);
+ if (rc)
+ rc = HTTP_HttpSendRequestW(lpwhr, NULL, 0, NULL, 0, 0, TRUE);
- }
++ }
+ }
}
- else
- rc = HTTP_HttpEndRequestW(lpwhr, dwFlags, dwContext);
WININET_Release( &lpwhr->hdr );
TRACE("%i <--\n",rc);
types = lpszAcceptTypes;
while (*types)
{
- __TRY
- {
- /* find out how many there are */
+ /* find out how many there are */
- if (*types && **types)
+ if (((ULONG_PTR)*types >> 16) && **types)
- {
- TRACE("accept type: %s\n", debugstr_a(*types));
- acceptTypesCount++;
- }
+ {
+ TRACE("accept type: %s\n", debugstr_a(*types));
+ acceptTypesCount++;
+ }
- }
- __EXCEPT_PAGE_FAULT
- {
- WARN("invalid accept type pointer\n");
- }
- __ENDTRY;
types++;
}
szAcceptTypes = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR *) * (acceptTypesCount+1));
if(lpwhr->hCacheFile)
CloseHandle(lpwhr->hCacheFile);
- HeapFree(GetProcessHeap(), 0, lpwhr->lpszCacheFile);
+ if(lpwhr->lpszCacheFile) {
+ DeleteFileW(lpwhr->lpszCacheFile); /* FIXME */
+ HeapFree(GetProcessHeap(), 0, lpwhr->lpszCacheFile);
+ }
- DeleteCriticalSection( &lpwhr->read_section );
WININET_Release(&lpwhr->lpHttpSession->hdr);
- destroy_authinfo(lpwhr->pAuthInfo);
- destroy_authinfo(lpwhr->pProxyAuthInfo);
-
HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath);
HeapFree(GetProcessHeap(), 0, lpwhr->lpszVerb);
HeapFree(GetProcessHeap(), 0, lpwhr->lpszRawHeaders);
if (!NETCON_connected(&lpwhr->netConnection))
return;
- INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
- INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
-
- NETCON_close(&lpwhr->netConnection);
-
- INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
- INTERNET_STATUS_CONNECTION_CLOSED, 0, 0);
- }
-
- static BOOL HTTP_GetRequestURL(http_request_t *req, LPWSTR buf)
+ if (lpwhr->pAuthInfo)
- {
+{
- LPHTTPHEADERW host_header;
-
- static const WCHAR formatW[] = {'h','t','t','p',':','/','/','%','s','%','s',0};
-
- host_header = HTTP_GetHeader(req, hostW);
- if(!host_header)
- return FALSE;
-
- sprintfW(buf, formatW, host_header->lpszValue, req->lpszPath); /* FIXME */
- return TRUE;
+ if (SecIsValidHandle(&lpwhr->pAuthInfo->ctx))
+ DeleteSecurityContext(&lpwhr->pAuthInfo->ctx);
+ if (SecIsValidHandle(&lpwhr->pAuthInfo->cred))
+ FreeCredentialsHandle(&lpwhr->pAuthInfo->cred);
+
+ HeapFree(GetProcessHeap(), 0, lpwhr->pAuthInfo->auth_data);
+ HeapFree(GetProcessHeap(), 0, lpwhr->pAuthInfo->scheme);
+ HeapFree(GetProcessHeap(), 0, lpwhr->pAuthInfo);
+ lpwhr->pAuthInfo = NULL;
- }
+}
-
- static BOOL HTTP_KeepAlive(http_request_t *lpwhr)
+ if (lpwhr->pProxyAuthInfo)
- {
+{
- WCHAR szVersion[10];
- WCHAR szConnectionResponse[20];
- DWORD dwBufferSize = sizeof(szVersion);
- BOOL keepalive = FALSE;
+ if (SecIsValidHandle(&lpwhr->pProxyAuthInfo->ctx))
+ DeleteSecurityContext(&lpwhr->pProxyAuthInfo->ctx);
+ if (SecIsValidHandle(&lpwhr->pProxyAuthInfo->cred))
+ FreeCredentialsHandle(&lpwhr->pProxyAuthInfo->cred);
- /* as per RFC 2068, S8.1.2.1, if the client is HTTP/1.1 then assume that
- * the connection is keep-alive by default */
- if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_VERSION, szVersion,
- &dwBufferSize, NULL) &&
- !strcmpiW(szVersion, g_szHttp1_1))
- {
- keepalive = TRUE;
+ HeapFree(GetProcessHeap(), 0, lpwhr->pProxyAuthInfo->auth_data);
+ HeapFree(GetProcessHeap(), 0, lpwhr->pProxyAuthInfo->scheme);
+ HeapFree(GetProcessHeap(), 0, lpwhr->pProxyAuthInfo);
+ lpwhr->pProxyAuthInfo = NULL;
}
- dwBufferSize = sizeof(szConnectionResponse);
- if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_PROXY_CONNECTION, szConnectionResponse, &dwBufferSize, NULL) ||
- HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_CONNECTION, szConnectionResponse, &dwBufferSize, NULL))
- {
- keepalive = !strcmpiW(szConnectionResponse, szKeepAlive);
- }
-
- return keepalive;
- }
-
- static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
- {
- http_request_t *req = (http_request_t*)hdr;
-
- switch(option) {
- case INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO:
- {
- http_session_t *lpwhs = req->lpHttpSession;
- INTERNET_DIAGNOSTIC_SOCKET_INFO *info = buffer;
-
- FIXME("INTERNET_DIAGNOSTIC_SOCKET_INFO stub\n");
+ INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
- if (*size < sizeof(INTERNET_DIAGNOSTIC_SOCKET_INFO))
- return ERROR_INSUFFICIENT_BUFFER;
- *size = sizeof(INTERNET_DIAGNOSTIC_SOCKET_INFO);
- /* FIXME: can't get a SOCKET from our connection since we don't use
- * winsock
- */
- info->Socket = 0;
- /* FIXME: get source port from req->netConnection */
- info->SourcePort = 0;
- info->DestPort = lpwhs->nHostPort;
- info->Flags = 0;
- if (HTTP_KeepAlive(req))
- info->Flags |= IDSI_FLAG_KEEP_ALIVE;
- if (lpwhs->lpAppInfo->lpszProxy && lpwhs->lpAppInfo->lpszProxy[0] != 0)
- info->Flags |= IDSI_FLAG_PROXY;
- if (req->netConnection.useSSL)
- info->Flags |= IDSI_FLAG_SECURE;
+ NETCON_close(&lpwhr->netConnection);
- return ERROR_SUCCESS;
+ INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_CONNECTION_CLOSED, 0, 0);
-}
+ }
- case INTERNET_OPTION_SECURITY_FLAGS:
+ static DWORD HTTPREQ_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
-{
+ {
- http_session_t *lpwhs;
- lpwhs = req->lpHttpSession;
-
- if (*size < sizeof(ULONG))
- return ERROR_INSUFFICIENT_BUFFER;
-
- *size = sizeof(DWORD);
- if (lpwhs->hdr.dwFlags & INTERNET_FLAG_SECURE)
- *(DWORD*)buffer = SECURITY_FLAG_SECURE;
- else
- *(DWORD*)buffer = 0;
- FIXME("Semi-STUB INTERNET_OPTION_SECURITY_FLAGS: %x\n",*(DWORD*)buffer);
- return ERROR_SUCCESS;
- }
+ WININETHTTPREQW *req = (WININETHTTPREQW*)hdr;
+ switch(option) {
case INTERNET_OPTION_HANDLE_TYPE:
TRACE("INTERNET_OPTION_HANDLE_TYPE\n");
return ERROR_INTERNET_INVALID_OPTION;
}
- /* read some more data into the read buffer (the read section must be held) */
- static BOOL read_more_data( http_request_t *req, int maxlen )
+ static DWORD HTTP_Read(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD *read, BOOL sync)
{
- int len;
-
- if (req->read_pos)
- {
- /* move existing data to the start of the buffer */
- if(req->read_size)
- memmove( req->read_buf, req->read_buf + req->read_pos, req->read_size );
- req->read_pos = 0;
- }
+ int bytes_read;
- if (maxlen == -1) maxlen = sizeof(req->read_buf);
-
- if(!NETCON_recv( &req->netConnection, req->read_buf + req->read_size,
- maxlen - req->read_size, 0, &len ))
- return FALSE;
-
- req->read_size += len;
- return TRUE;
- }
+ if(!NETCON_recv(&req->netConnection, buffer, min(size, req->dwContentLength - req->dwContentRead),
+ sync ? MSG_WAITALL : 0, &bytes_read)) {
+ if(req->dwContentLength != -1 && req->dwContentRead != req->dwContentLength)
+ ERR("not all data received %d/%d\n", req->dwContentRead, req->dwContentLength);
- /* remove some amount of data from the read buffer (the read section must be held) */
- static void remove_data( http_request_t *req, int count )
- {
- if (!(req->read_size -= count)) req->read_pos = 0;
- else req->read_pos += count;
+ /* always return success, even if the network layer returns an error */
+ *read = 0;
+ HTTP_FinishedReading(req);
+ return ERROR_SUCCESS;
- }
+}
- static BOOL read_line( http_request_t *req, LPSTR buffer, DWORD *len )
- {
- int count, bytes_read, pos = 0;
+ req->dwContentRead += bytes_read;
+ *read = bytes_read;
- EnterCriticalSection( &req->read_section );
- for (;;)
- {
- BYTE *eol = memchr( req->read_buf + req->read_pos, '\n', req->read_size );
+ if(req->lpszCacheFile) {
+ BOOL res;
+ DWORD dwBytesWritten;
- if (eol)
- {
- count = eol - (req->read_buf + req->read_pos);
- bytes_read = count + 1;
+ res = WriteFile(req->hCacheFile, buffer, bytes_read, &dwBytesWritten, NULL);
+ if(!res)
+ WARN("WriteFile failed: %u\n", GetLastError());
- }
+ }
- else count = bytes_read = req->read_size;
- count = min( count, *len - pos );
- memcpy( buffer + pos, req->read_buf + req->read_pos, count );
- pos += count;
- remove_data( req, bytes_read );
- if (eol) break;
+ if(!bytes_read && (req->dwContentRead == req->dwContentLength))
+ HTTP_FinishedReading(req);
- if (!read_more_data( req, -1 ) || !req->read_size)
- {
- *len = 0;
- TRACE( "returning empty string\n" );
- LeaveCriticalSection( &req->read_section );
- return FALSE;
+ return ERROR_SUCCESS;
-}
+ }
- }
- LeaveCriticalSection( &req->read_section );
- if (pos < *len)
+ static DWORD get_chunk_size(const char *buffer)
-{
+ {
- if (pos && buffer[pos - 1] == '\r') pos--;
- *len = pos + 1;
- }
- buffer[*len - 1] = 0;
- TRACE( "returning %s\n", debugstr_a(buffer));
- return TRUE;
- }
+ const char *p;
+ DWORD size = 0;
- /* discard data contents until we reach end of line (the read section must be held) */
- static BOOL discard_eol( http_request_t *req )
+ for (p = buffer; *p; p++)
- {
+{
- do
- {
- BYTE *eol = memchr( req->read_buf + req->read_pos, '\n', req->read_size );
- if (eol)
- {
- remove_data( req, (eol + 1) - (req->read_buf + req->read_pos) );
- break;
+ if (*p >= '0' && *p <= '9') size = size * 16 + *p - '0';
+ else if (*p >= 'a' && *p <= 'f') size = size * 16 + *p - 'a' + 10;
+ else if (*p >= 'A' && *p <= 'F') size = size * 16 + *p - 'A' + 10;
+ else if (*p == ';') break;
- }
+ }
- req->read_pos = req->read_size = 0; /* discard everything */
- if (!read_more_data( req, -1 )) return FALSE;
- } while (req->read_size);
- return TRUE;
+ return size;
}
- /* read the size of the next chunk (the read section must be held) */
- static BOOL start_next_chunk( http_request_t *req )
+ static DWORD HTTP_ReadChunked(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD *read, BOOL sync)
{
- DWORD chunk_size = 0;
+ char reply[MAX_REPLY_LEN], *p = buffer;
+ DWORD buflen, to_read, to_write = size;
+ int bytes_read;
- if (!req->dwContentLength) return TRUE;
- if (req->dwContentLength == req->dwContentRead)
- {
- /* read terminator for the previous chunk */
- if (!discard_eol( req )) return FALSE;
- req->dwContentLength = ~0u;
- req->dwContentRead = 0;
- }
+ *read = 0;
for (;;)
{
- while (req->read_size)
- {
- char ch = req->read_buf[req->read_pos];
- if (ch >= '0' && ch <= '9') chunk_size = chunk_size * 16 + ch - '0';
- else if (ch >= 'a' && ch <= 'f') chunk_size = chunk_size * 16 + ch - 'a' + 10;
- else if (ch >= 'A' && ch <= 'F') chunk_size = chunk_size * 16 + ch - 'A' + 10;
- else if (ch == ';' || ch == '\r' || ch == '\n')
- {
- TRACE( "reading %u byte chunk\n", chunk_size );
- req->dwContentLength = chunk_size;
- req->dwContentRead = 0;
- if (!discard_eol( req )) return FALSE;
- return TRUE;
- }
- remove_data( req, 1 );
- }
- if (!read_more_data( req, -1 )) return FALSE;
- if (!req->read_size)
- {
- req->dwContentLength = req->dwContentRead = 0;
- return TRUE;
- }
- }
- }
+ if (*read == size) break;
- /* check if we have reached the end of the data to read (the read section must be held) */
- static BOOL end_of_read_data( http_request_t *req )
+ if (req->dwContentLength == ~0UL) /* new chunk */
- {
+{
- if (req->gzip_stream) return req->gzip_stream->end_of_data && !req->gzip_stream->buf_size;
- if (req->read_chunked) return (req->dwContentLength == 0);
- if (req->dwContentLength == ~0u) return FALSE;
- return (req->dwContentLength == req->dwContentRead);
- }
+ buflen = sizeof(reply);
+ if (!NETCON_getNextLine(&req->netConnection, reply, &buflen)) break;
- /* fetch some more data into the read buffer (the read section must be held) */
- static BOOL refill_buffer( http_request_t *req )
+ if (!(req->dwContentLength = get_chunk_size(reply)))
- {
+{
- int len = sizeof(req->read_buf);
-
- if (req->read_chunked && (req->dwContentLength == ~0u || req->dwContentLength == req->dwContentRead))
- {
- if (!start_next_chunk( req )) return FALSE;
+ /* zero sized chunk marks end of transfer; read any trailing headers and return */
+ HTTP_GetResponseHeaders(req, FALSE);
+ break;
- }
- }
+ }
-
- if (req->dwContentLength != ~0u) len = min( len, req->dwContentLength - req->dwContentRead );
- if (len <= req->read_size) return TRUE;
-
- if (!read_more_data( req, len )) return FALSE;
- if (!req->read_size) req->dwContentLength = req->dwContentRead = 0;
- return TRUE;
+}
+ to_read = min(to_write, req->dwContentLength - req->dwContentRead);
- static DWORD read_gzip_data(http_request_t *req, BYTE *buf, int size, BOOL sync, int *read_ret)
+ if (!NETCON_recv(&req->netConnection, p, to_read, sync ? MSG_WAITALL : 0, &bytes_read))
- {
+{
- DWORD ret = ERROR_SUCCESS;
- int read = 0;
-
- #ifdef HAVE_ZLIB
- z_stream *zstream = &req->gzip_stream->zstream;
- int zres;
+ if (bytes_read != to_read)
+ ERR("Not all data received %d/%d\n", bytes_read, to_read);
- while(read < size && !req->gzip_stream->end_of_data) {
- if(!req->read_size) {
- if(!sync || !refill_buffer(req))
+ /* always return success, even if the network layer returns an error */
+ *read = 0;
- break;
+ break;
}
+ if (!bytes_read) break;
- zstream->next_in = req->read_buf+req->read_pos;
- zstream->avail_in = req->read_size;
- zstream->next_out = buf+read;
- zstream->avail_out = size-read;
- zres = inflate(zstream, Z_FULL_FLUSH);
- read = size - zstream->avail_out;
- remove_data(req, req->read_size-zstream->avail_in);
- if(zres == Z_STREAM_END) {
- TRACE("end of data\n");
- req->gzip_stream->end_of_data = TRUE;
- inflateEnd(&req->gzip_stream->zstream);
- }else if(zres != Z_OK) {
- WARN("inflate failed %d\n", zres);
- if(!read)
- ret = ERROR_INTERNET_DECODING_FAILED;
- break;
- }
- }
- #endif
-
- *read_ret = read;
- return ret;
- }
+ req->dwContentRead += bytes_read;
+ to_write -= bytes_read;
+ *read += bytes_read;
- static void refill_gzip_buffer(http_request_t *req)
+ if (req->lpszCacheFile)
- {
+{
- DWORD res;
- int len;
-
- if(!req->gzip_stream || !req->read_size || req->gzip_stream->buf_size == sizeof(req->gzip_stream->buf))
- return;
+ DWORD dwBytesWritten;
- if(req->gzip_stream->buf_pos) {
- if(req->gzip_stream->buf_size)
- memmove(req->gzip_stream->buf, req->gzip_stream->buf + req->gzip_stream->buf_pos, req->gzip_stream->buf_size);
- req->gzip_stream->buf_pos = 0;
+ if (!WriteFile(req->hCacheFile, p, bytes_read, &dwBytesWritten, NULL))
+ WARN("WriteFile failed: %u\n", GetLastError());
- }
+ }
+ p += bytes_read;
- res = read_gzip_data(req, req->gzip_stream->buf + req->gzip_stream->buf_size,
- sizeof(req->gzip_stream->buf) - req->gzip_stream->buf_size, FALSE, &len);
- if(res == ERROR_SUCCESS)
- req->gzip_stream->buf_size += len;
- }
+ if (req->dwContentRead == req->dwContentLength) /* chunk complete */
+ {
+ req->dwContentRead = 0;
+ req->dwContentLength = ~0UL;
- /* return the size of data available to be read immediately (the read section must be held) */
- static DWORD get_avail_data( http_request_t *req )
+ buflen = sizeof(reply);
+ if (!NETCON_getNextLine(&req->netConnection, reply, &buflen))
- {
+{
- if (req->gzip_stream) {
- refill_gzip_buffer(req);
- return req->gzip_stream->buf_size;
+ ERR("Malformed chunk\n");
+ *read = 0;
+ break;
- }
- }
+ }
- if (req->read_chunked && (req->dwContentLength == ~0u || req->dwContentLength == req->dwContentRead))
- return 0;
- return min( req->read_size, req->dwContentLength - req->dwContentRead );
+}
-
- static void HTTP_ReceiveRequestData(http_request_t *req, BOOL first_notif)
- {
- INTERNET_ASYNC_RESULT iar;
-
- TRACE("%p\n", req);
-
- EnterCriticalSection( &req->read_section );
- if (refill_buffer( req )) {
- iar.dwResult = (DWORD_PTR)req->hdr.hInternet;
- iar.dwError = first_notif ? 0 : get_avail_data(req);
- }else {
- iar.dwResult = 0;
- iar.dwError = INTERNET_GetLastError();
}
- LeaveCriticalSection( &req->read_section );
-
- INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, &iar,
- sizeof(INTERNET_ASYNC_RESULT));
+ if (!*read) HTTP_FinishedReading(req);
+ return ERROR_SUCCESS;
}
- /* read data from the http connection (the read section must be held) */
- static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD *read, BOOL sync)
+ static DWORD HTTPREQ_Read(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD *read, BOOL sync)
{
- BOOL finished_reading = FALSE;
- int len, bytes_read = 0;
- DWORD ret = ERROR_SUCCESS;
-
- EnterCriticalSection( &req->read_section );
+ WCHAR encoding[20];
+ DWORD buflen = sizeof(encoding);
+ static const WCHAR szChunked[] = {'c','h','u','n','k','e','d',0};
- if (req->read_chunked && (req->dwContentLength == ~0u || req->dwContentLength == req->dwContentRead))
+ if (HTTP_HttpQueryInfoW(req, HTTP_QUERY_TRANSFER_ENCODING, encoding, &buflen, NULL) &&
+ !strcmpiW(encoding, szChunked))
{
- if (!start_next_chunk( req )) goto done;
+ return HTTP_ReadChunked(req, buffer, size, read, sync);
}
-
- if(req->gzip_stream) {
- if(req->gzip_stream->buf_size) {
- bytes_read = min(req->gzip_stream->buf_size, size);
- memcpy(buffer, req->gzip_stream->buf + req->gzip_stream->buf_pos, bytes_read);
- req->gzip_stream->buf_pos += bytes_read;
- req->gzip_stream->buf_size -= bytes_read;
- }else if(!req->read_size && !req->gzip_stream->end_of_data) {
- refill_buffer(req);
- }
-
- if(size > bytes_read) {
- ret = read_gzip_data(req, (BYTE*)buffer+bytes_read, size-bytes_read, sync, &len);
- if(ret == ERROR_SUCCESS)
- bytes_read += len;
- }
-
- finished_reading = req->gzip_stream->end_of_data && !req->gzip_stream->buf_size;
- }else {
- if (req->dwContentLength != ~0u) size = min( size, req->dwContentLength - req->dwContentRead );
-
- if (req->read_size) {
- bytes_read = min( req->read_size, size );
- memcpy( buffer, req->read_buf + req->read_pos, bytes_read );
- remove_data( req, bytes_read );
- }
-
- if (size > bytes_read && (!bytes_read || sync)) {
- if (NETCON_recv( &req->netConnection, (char *)buffer + bytes_read, size - bytes_read,
- sync ? MSG_WAITALL : 0, &len))
- bytes_read += len;
- /* always return success, even if the network layer returns an error */
+ else
+ return HTTP_Read(req, buffer, size, read, sync);
-}
+ }
- finished_reading = !bytes_read && req->dwContentRead == req->dwContentLength;
- }
- done:
- req->dwContentRead += bytes_read;
- *read = bytes_read;
-
- TRACE( "retrieved %u bytes (%u/%u)\n", bytes_read, req->dwContentRead, req->dwContentLength );
- LeaveCriticalSection( &req->read_section );
-
- if(ret == ERROR_SUCCESS && req->lpszCacheFile) {
- BOOL res;
- DWORD dwBytesWritten;
-
- res = WriteFile(req->hCacheFile, buffer, bytes_read, &dwBytesWritten, NULL);
- if(!res)
- WARN("WriteFile failed: %u\n", GetLastError());
- }
-
- if(finished_reading)
- HTTP_FinishedReading(req);
-
- return ret;
- }
-
-
- static DWORD HTTPREQ_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DWORD *read)
+ static DWORD HTTPREQ_ReadFile(WININETHANDLEHEADER *hdr, void *buffer, DWORD size, DWORD *read)
{
- http_request_t *req = (http_request_t*)hdr;
+ WININETHTTPREQW *req = (WININETHTTPREQW*)hdr;
return HTTPREQ_Read(req, buffer, size, read, TRUE);
}
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
- if ((hdr->dwFlags & INTERNET_FLAG_ASYNC) && !get_avail_data(req))
+ if (hdr->dwFlags & INTERNET_FLAG_ASYNC) {
+ DWORD available = 0;
+
+ NETCON_query_data_available(&req->netConnection, &available);
+ if (!available)
- {
- WORKREQUEST workRequest;
+ {
+ WORKREQUEST workRequest;
- if (TryEnterCriticalSection( &req->read_section ))
- {
- if (get_avail_data(req))
- {
- res = HTTPREQ_Read(req, buffers->lpvBuffer, buffers->dwBufferLength,
- &buffers->dwBufferLength, FALSE);
- LeaveCriticalSection( &req->read_section );
- goto done;
- }
- LeaveCriticalSection( &req->read_section );
- }
-
- workRequest.asyncproc = HTTPREQ_AsyncReadFileExAProc;
+ workRequest.asyncproc = HTTPREQ_AsyncReadFileExProc;
- workRequest.hdr = WININET_AddRef(&req->hdr);
- workRequest.u.InternetReadFileExA.lpBuffersOut = buffers;
+ workRequest.hdr = WININET_AddRef(&req->hdr);
+ workRequest.u.InternetReadFileExA.lpBuffersOut = buffers;
- INTERNET_AsyncCall(&workRequest);
+ INTERNET_AsyncCall(&workRequest);
- return ERROR_IO_PENDING;
- }
+ return ERROR_IO_PENDING;
+ }
+ }
res = HTTPREQ_Read(req, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength,
!(flags & IRF_NO_WAIT));
return res;
}
- static void HTTPREQ_AsyncReadFileExWProc(WORKREQUEST *workRequest)
+ static BOOL HTTPREQ_WriteFile(WININETHANDLEHEADER *hdr, const void *buffer, DWORD size, DWORD *written)
{
- struct WORKREQ_INTERNETREADFILEEXW const *data = &workRequest->u.InternetReadFileExW;
- http_request_t *req = (http_request_t*)workRequest->hdr;
- INTERNET_ASYNC_RESULT iar;
- DWORD res;
-
- TRACE("INTERNETREADFILEEXW %p\n", workRequest->hdr);
-
- res = HTTPREQ_Read(req, data->lpBuffersOut->lpvBuffer,
- data->lpBuffersOut->dwBufferLength, &data->lpBuffersOut->dwBufferLength, TRUE);
+ LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW)hdr;
-&nb