Esempio n. 1
0
/*!
	AAテキストを確保して取り込む
	@param[in]	hWnd	ウインドウハンドル
	@param[in]	pcArts	AAテキストSJIS
	@return		追加後のアイテム総数
*/
UINT DraughtItemAdding( HWND hWnd, LPSTR pcArts )
{
	UINT_PTR	cbSize;
	AAMATRIX	stItem;

	INT_PTR	iItems;


	StringCchLengthA( pcArts, STRSAFE_MAX_CCH, &cbSize );

	stItem.cbItem = cbSize;
	stItem.pcItem = (LPSTR)malloc( (cbSize + 1) );
	ZeroMemory( stItem.pcItem, (cbSize + 1) );
	StringCchCopyA( stItem.pcItem, (cbSize + 1), pcArts );


	DraughtAaImageing( hWnd, &stItem );


	gvcDrtItems.push_back( stItem );

	do	//	はみだしてたら?
	{
		iItems = gvcDrtItems.size( );
		if( (TPNL_HORIZ * TPNL_VERTI) < iItems ){	DraughtItemDelete(  0 );	}

	}while( (TPNL_HORIZ * TPNL_VERTI) < iItems );

	return iItems;
}
Esempio n. 2
0
/*
 * TclSetWinError
 *
 *   Sets the interpreter's errorCode variable.
 *
 * Arguments:
 *   interp    - Current interpreter.
 *   errorCode - Windows error code.
 *
 * Returns:
 *   The message that is associated with the error code.
 */
char *
TclSetWinError(
    Tcl_Interp *interp,
    DWORD errorCode
    )
{
    char errorId[12];
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    StringCchPrintfA(errorId, ARRAYSIZE(errorId), "%lu", errorCode);

    if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        errorCode,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        tsdPtr->message,
        ARRAYSIZE(tsdPtr->message),
        NULL) == 0) {
        StringCchCopyA(tsdPtr->message, ARRAYSIZE(tsdPtr->message), "unknown error");
    } else {
        size_t length;
        StringCchLengthA(tsdPtr->message, ARRAYSIZE(tsdPtr->message), &length);

        /* Remove trailing CR/LF. */
        if (length >= 2 && tsdPtr->message[length-2] == '\r' && tsdPtr->message[length-1] == '\n') {
            tsdPtr->message[length-2] = '\0';
        }
    }

    Tcl_SetErrorCode(interp, "WINDOWS", errorId, tsdPtr->message, NULL);
    return tsdPtr->message;
}
Esempio n. 3
0
//
// PathAddBackslashEx
//
// Checked version of PathAddBackslash which also handles quoted paths
//
// Return values:  S_OK          - backslash appended
//                 S_FALSE       - path already ended with a backslash
//                 E_OUTOFMEMORY - buffer too small
//                 E_FAIL        - other failure (invalid input string)
//
HRESULT PathAddBackslashExA(LPSTR pszPath, size_t cchPath)
{
    ASSERT(cchPath <= STRSAFE_MAX_CCH);
    ASSERT(nullptr != pszPath); ASSERT(0 != cchPath);

    HRESULT hr = E_FAIL;
    size_t cchCurrentLength = 0;

    if (SUCCEEDED(StringCchLengthA(pszPath, cchPath, &cchCurrentLength)))
    {
        bool bHasQuote = false;
        LPSTR ptzEnd = pszPath + cchCurrentLength;

        if ((ptzEnd > pszPath) && (*(ptzEnd-1) == _T('\"')))
        {
            --ptzEnd;
            bHasQuote = true;
        }

        if (ptzEnd > pszPath)
        {
            if (*(ptzEnd-1) != _T('\\'))
            {
                if (cchPath - cchCurrentLength > 1)
                {
                    if (bHasQuote)
                    {
                        *(ptzEnd+1) = *ptzEnd;
                    }

                    *ptzEnd = _T('\\');

                    if (bHasQuote)
                    {
                        ++ptzEnd;
                    }

                    ASSERT((size_t)(ptzEnd - pszPath) < cchPath);
                    *(ptzEnd+1) = _T('\0');

                    hr = S_OK;
                }
                else
                {
                    hr = E_OUTOFMEMORY;
                }
            }
            else
            {
                hr = S_FALSE;
            }
        }
    }

    return hr;
}
Esempio n. 4
0
LPSTR UnicodeStr4CodeToUTF8Str(LPSTR in)
{
	LPSTR temp;
	unsigned int code, help;
	CHAR utf8[5];
	size_t length;
	while(temp = StrChrA(in, '\\'), temp != NULL)
	{
		if((temp[1] == 'u')||(temp[1] == 'U'))
		{
			temp[0] = '\0';
			StringCchLengthA(in, STRSAFE_MAX_CCH, &length);
			CHAR A[length+1];
			StringCchCopyA(A, length+1, in);
			StringCchLengthA(temp+6, STRSAFE_MAX_CCH, &length);
			CHAR B[length+1];
			StringCchCopyA(B, length+1, temp+6);
			temp[6] = '\0';
			CHAR hex_code[7];
			StringCchCopyA(hex_code, 7, "0x");
			CharLowerA(temp+2);
			StringCchCatA(hex_code, 7, temp+2);
			if(StrToIntExA(hex_code, STIF_SUPPORT_HEX, (int *)&code) == TRUE)
			{
				help = code;
				if(code <= 0x007F)
				{
					utf8[0] = code;
					utf8[1] = '\0';
				}
				else if(code <= 0x07FF)
				{
					utf8[0] = 0xC0+(help >> 6);
					utf8[1] = 0x80+(code&0x3F);
					utf8[2] = '\0';
				}
				else if(code <= 0xFFFF)
Esempio n. 5
0
void CharToWString( const CHAR* source, std::wstring& dest )
{
	try
	{
		size_t size = 0;
		StringCchLengthA(source, STRSAFE_MAX_CCH, &size);
		size++;

		WCHAR* tmp = (WCHAR*) alloca( size * sizeof(WCHAR) );
		StringCchPrintfW(tmp, size, L"%S", source);

		dest = tmp;
	}
	catch( ... )
	{}
}
Esempio n. 6
0
static inline HRESULT StringCchCatA(char* pszDest, size_t cchDest, const char* pszSrc)
{
    HRESULT hr;
    size_t cchDestCurrent;

    if (cchDest > 2147483647)
    {
        return ERROR_INVALID_PARAMETER;
    }

    hr = StringCchLengthA(pszDest, cchDest, &cchDestCurrent);

    if (SUCCEEDED(hr))
    {
        hr = StringCchCopyA(pszDest + cchDestCurrent,
                            cchDest - cchDestCurrent,
                            pszSrc);
    }

    return hr;
}
Esempio n. 7
0
HRESULT StringCbLengthA(
        LPCSTR psz,
        size_t cbMax,
        size_t *pcb){
    return StringCchLengthA(psz, cbMax, pcb);
}
Esempio n. 8
0
/*!
	クリップボードに変更があった場合の処理・自分からの変更に反応しないようにせにゃ
	@param[in]	hWnd	ウインドウハンドル・使わないか
	@return	HRESULT	終了状態コード
*/
HRESULT ClipStealDoing( HWND hWnd )
{
	LPTSTR		ptTexts;
	LPSTR		pcStrs;
	CHAR		acBuffer[MAX_STRING];
	TCHAR		atMsg[MAX_STRING];

	UINT_PTR	cbSize, cbSplSz;
	DWORD		wrote;

	HANDLE	hFile;

	SYSTEMTIME	stTime;


	//	保存するファイル指定が無いならナニもしない
	if( NULL == gatClipFile[0] ){	return E_NOTIMPL;	}

	//	クリップスティール機能有効?
	if( !(gbClipSteal) ){	return  S_FALSE;	}


	ptTexts = ClipboardDataGet( NULL );
	if( !(ptTexts) ){	return E_ACCESSDENIED;	}
	//	クリップされたのが文字列ではなかったら直ぐ終わる

	//	SJIS型に変換
	pcStrs = SjisEncodeAlloc( ptTexts );
	StringCchLengthA( pcStrs, STRSAFE_MAX_CCH, &cbSize );

	//	ゲットしたコピペ文字列の保存処理
	hFile = CreateFile( gatClipFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
	if( INVALID_HANDLE_VALUE != hFile )
	{
		SetFilePointer( hFile, 0, NULL, FILE_END );

		if( gIsAST )
		{
			GetLocalTime( &stTime );
			StringCchPrintfA( acBuffer, MAX_STRING, ("[AA][%04u/%02u/%02u %02u:%02u:%02u]\r\n"),
				stTime.wYear, stTime.wMonth, stTime.wDay, stTime.wHour, stTime.wMinute, stTime.wSecond );
			StringCchLengthA( acBuffer, MAX_STRING, &cbSplSz );
			WriteFile( hFile, acBuffer, cbSplSz, &wrote, NULL );
		}

		WriteFile( hFile, pcStrs, cbSize, &wrote, NULL );

		if( gIsAST ){	StringCchCopyA( acBuffer, MAX_STRING, ("\r\n") );	}
		else{	StringCchCopyA( acBuffer, MAX_STRING, ("\r\n[SPLIT]\r\n") );	}
		StringCchLengthA( acBuffer, MAX_STRING, &cbSplSz );
		WriteFile( hFile, acBuffer, cbSplSz, &wrote, NULL );

		SetEndOfFile( hFile );
		CloseHandle( hFile );
	}

	FREE( ptTexts );
	FREE( pcStrs );

	//	保存したメッセージが必要
	if( gGetMsgOn )
	{
		StringCchPrintf( atMsg, MAX_STRING, TEXT("%u Byte 取得"), cbSize );
		TaskTrayIconBalloon( hWnd, TEXT("コピーされた文字列を保存したよ。"), atMsg, 1 );
	}

	return S_OK;
}
Esempio n. 9
0
/*!
	ページ全体を確保する・freeは呼んだ方でやる
	@param[in]	bStyle	1ユニコードかシフトJIS
	@param[out]	*pText	確保した領域を返す・ワイド文字かマルチ文字になる・NULLだと必要バイト数を返すのみ
	@return				確保したバイト数・NULLターミネータも含む
*/
INT DocPageTextAllGetAlloc( UINT bStyle, LPVOID *pText )
{
	//	SJISの場合は、ユニコード文字は&#dddd;で確保される

	UINT_PTR	iLines, i, iLetters, j;
	UINT_PTR	cchSize;
	INT_PTR		iSize;

	LPTSTR		ptData;
	LPSTR		pcStr;

	string	srString;	//	ユニコード・シフトJISで確保
	wstring	wsString;

	LINE_ITR	itLine;


	srString.clear( );
	wsString.clear( );

	if( gitFileIt->vcCont.at( gixFocusPage ).ptRawData )	//	生データ状態なら
	{
		ptData = (*gitFileIt).vcCont.at( gixFocusPage ).ptRawData;
		StringCchLength( ptData, STRSAFE_MAX_CCH, &cchSize );

		if( bStyle & D_UNI )	//	ユニコードである
		{
			iSize = (cchSize+1) * sizeof(TCHAR);	//	NULLターミネータ分足す

			if( pText )
			{
				*pText = (LPTSTR)malloc( iSize );
				ZeroMemory( *pText, iSize );
				StringCchCopy( (LPTSTR)(*pText), cchSize, ptData );
			}
		}
		else
		{
			pcStr = SjisEncodeAlloc( ptData );
			if( pcStr )
			{
				StringCchLengthA( pcStr, STRSAFE_MAX_CCH, &cchSize );
				iSize = cchSize + 1;	//	NULLターミネータ分足す

				if( pText ){	*pText =  pcStr;	}
				else{	FREE( pcStr );	}
			}
		}
	}
	else
	{
		//	ページ全体の行数
		iLines = DocNowFilePageLineCount( );

		itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin();

		for( i = 0; iLines > i; i++, itLine++ )
		{
			//	各行の文字数
			iLetters = itLine->vcLine.size( );

			if( bStyle & D_UNI )
			{
				for( j = 0; iLetters > j; j++ )
				{
					wsString += itLine->vcLine.at( j ).cchMozi;
				}

				if( iLines > (i+1) )	wsString += wstring( CH_CRLFW );
			}
			else
			{
				for( j = 0; iLetters > j; j++ )
				{
					srString +=  string( itLine->vcLine.at( j ).acSjis );
				}

				if( iLines > (i+1) )	srString +=  string( CH_CRLFA );
			}
		}

		if( bStyle & D_UNI )	//	ユニコードである
		{
			cchSize = wsString.size(  ) + 1;	//	NULLターミネータ分足す
			iSize = cchSize * sizeof(TCHAR);	//	ユニコードなのでバイト数は2倍である

			if( pText )
			{
				*pText = (LPTSTR)malloc( iSize );
				ZeroMemory( *pText, iSize );
				StringCchCopy( (LPTSTR)(*pText), cchSize, wsString.c_str( ) );
			}
		}
		else
		{
			iSize = srString.size( ) + 1;	//	NULLターミネータ分足す

			if( pText )
			{
				*pText = (LPSTR)malloc( iSize );
				ZeroMemory( *pText, iSize );
				StringCchCopyA( (LPSTR)(*pText), iSize, srString.c_str( ) );
			}
		}
	}

	return iSize;
}
Esempio n. 10
0
VOID
cdecl
PlotDbgPrint(
    LPCSTR   pszFormat,
    ...
)

/*++

Routine Description:

    This fucntion output the debug informat to the debugger


Arguments:

    pszFormat   - format string

    ...         - variable data


Return Value:


    VOID

Author:

    15-Nov-1993 Mon 17:57:59 created


Revision History:


--*/

{
    va_list         vaList;

#if defined(UMODE) || defined(USERMODE_DRIVER)

    static WCHAR    wOutBuf[768];
    static WCHAR    wFormatBuf[256];
    size_t          cch;

    //
    // We assume that UNICODE flag is turn on for the compilation, bug the
    // format string passed to here is ASCII version, so we need to convert
    // it to LPWSTR before the wvsprintf()
    //

    if (!SUCCEEDED(StringCchLengthA(pszFormat, CCHOF(wFormatBuf), &cch)))
    {
        return;
    }

    va_start(vaList, pszFormat);
    MultiByteToWideChar(CP_ACP, 0, pszFormat, -1, wFormatBuf, CCHOF(wFormatBuf));
    if (!SUCCEEDED(StringCchVPrintfW(wOutBuf, CCHOF(wOutBuf), wFormatBuf, vaList)))
    {
        return;
    }
    va_end(vaList);

    OutputDebugString((LPCTSTR)wOutBuf);
    OutputDebugString(TEXT("\n"));

#else

    va_start(vaList, pszFormat);
    EngDebugPrint("PLOT",pszFormat,vaList);
    va_end(vaList);

#endif
}
Esempio n. 11
0
/*!
	ドラフトボードの内容をファイルに書き出す
	@param[in]	hWnd	ウインドウハンドル
	@param[in]	ptPath	未使用
*/
HRESULT DraughtItemExport( HWND hWnd, LPTSTR ptPath )
{
	CONST CHAR	cacSplit[] = ("[SPLIT]\r\n");	//	9BYTE

	UINT_PTR	dItems, cbSize;
	TCHAR		atPath[MAX_PATH], atName[MAX_PATH];
	BOOLEAN		bOpened;
	OPENFILENAME	stOpenFile;

	MAAM_ITR	itItem;

	HANDLE	hFile;
	DWORD	wrote;


	dItems = gvcDrtItems.size();
	if( 0 >= dItems )	return E_NOTIMPL;	//	空なら何もしない

	//ファイル名確定
	ZeroMemory( atPath, sizeof(atPath) );
	ZeroMemory( atName, sizeof(atName) );

	ZeroMemory( &stOpenFile, sizeof(OPENFILENAME) );
	stOpenFile.lStructSize     = sizeof(OPENFILENAME);
	stOpenFile.hwndOwner       = ghPtWnd;
	stOpenFile.lpstrFilter     = TEXT("複数行テンプレファイル(*.mlt)\0*.mlt\0全ての形式(*.*)\0*.*\0\0");
	stOpenFile.nFilterIndex    = 1;
	stOpenFile.lpstrFile       = atPath;
	stOpenFile.nMaxFile        = MAX_PATH;
	stOpenFile.lpstrFileTitle  = atName;
	stOpenFile.nMaxFileTitle   = MAX_PATH;
	stOpenFile.lpstrTitle      = TEXT("保存するファイル名を指定してね");
	stOpenFile.Flags           = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
	stOpenFile.lpstrDefExt     = TEXT("mlt");

	//ここで FileOpenDialogue を出す
	bOpened = GetSaveFileName( &stOpenFile );
	wrote = CommDlgExtendedError();

	TRACE( TEXT("ファイル保存ダイヤログ通過[%X]"), wrote );

#ifndef _ORRVW
	ViewFocusSet(  );
#endif
	if( !(bOpened) ){	return  E_ABORT;	}	//	キャンセルしてたら何もしない

	hFile = CreateFile( atPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
	if( INVALID_HANDLE_VALUE == hFile ){	return E_HANDLE;	}

	SetFilePointer( hFile, 0, NULL, FILE_BEGIN );

	for( itItem = gvcDrtItems.begin(); gvcDrtItems.end() != itItem; itItem++ )
	{
		StringCchLengthA( itItem->pcItem, STRSAFE_MAX_LENGTH, &cbSize );
		
		WriteFile( hFile, itItem->pcItem, cbSize, &wrote, NULL );
		WriteFile( hFile, cacSplit, 9, &wrote, NULL );	//	固定値注意
	}

	CloseHandle( hFile );

	MessageBox( hWnd, TEXT("ファイルに保存したよ"), TEXT("お燐からのお知らせ"), MB_OK | MB_ICONINFORMATION );

	return S_OK;
}
Esempio n. 12
0
/*!
	Targetアイテムを使う・クルップボードへ・他に使いたいときは?
	@param[in]	hWnd	ウインドウハンドル
	@param[in]	id		動作モードID
	@return		HRESULT	終了状態コード
*/
HRESULT DraughtItemUse( HWND hWnd, INT id )
{
	LPSTR		pcAaItem;
	INT_PTR		iItems, i, iOffset, iTarget;
	UINT_PTR	cbSize;
	UINT		dMode;
	MAAM_ITR	itItem;

	if( gbThumb )	//	サムネモード
	{
		iOffset = gdVwTop * TPNL_HORIZ;
		iTarget = iOffset + giTarget;

		pcAaItem = AacAsciiArtGet( iTarget );
		if( !(pcAaItem) )	return E_OUTOFMEMORY;

		switch( id )
		{
			case IDM_DRAUGHT_INSERTEDIT:	dMode = MAA_INSERT;		break;
			case IDM_DRAUGHT_INTERRUPTEDIT:	dMode = MAA_INTERRUPT;	break;
			case IDM_DRAUGHT_LAYERBOX:		dMode = MAA_LAYERED;	break;
			default:
			case IDM_DRAUGHT_UNICLIP:		dMode = MAA_UNICLIP;	break;
			case IDM_DRAUGHT_SJISCLIP:		dMode = MAA_SJISCLIP;	break;

			case IDM_THUMB_DRAUGHT_ADD:		dMode = MAA_DRAUGHT;	break;
		}
		StringCchLengthA( pcAaItem, STRSAFE_MAX_CCH, &cbSize );

		ViewMaaMaterialise( hWnd, pcAaItem, cbSize, dMode );

		if( id != IDM_THUMB_DRAUGHT_ADD )
		{
			//	ここでお気に入りに入れる・大丈夫か?
			if( SUCCEEDED( AaItemsFavUpload( pcAaItem, cbSize ) ) )
			{
				FavContsRedrawRequest( hWnd );
			}
		}

		FREE(pcAaItem);
	}
	else
	{
		iItems = gvcDrtItems.size( );	//	現在個数
		if( 0 >= iItems )	return E_OUTOFMEMORY;

		for( i = 0, itItem = gvcDrtItems.begin(); gvcDrtItems.end() != itItem; i++, itItem++ )
		{
			if( giTarget == i )	//	ヒット
			{
				switch( id )
				{
					case IDM_DRAUGHT_INSERTEDIT:	dMode = MAA_INSERT;		break;
					case IDM_DRAUGHT_INTERRUPTEDIT:	dMode = MAA_INTERRUPT;	break;
					case IDM_DRAUGHT_LAYERBOX:		dMode = MAA_LAYERED;	break;
					default:
					case IDM_DRAUGHT_UNICLIP:		dMode = MAA_UNICLIP;	break;
					case IDM_DRAUGHT_SJISCLIP:		dMode = MAA_SJISCLIP;	break;
				}
				StringCchLengthA( itItem->pcItem, STRSAFE_MAX_CCH, &cbSize );

				ViewMaaMaterialise( hWnd, itItem->pcItem, cbSize, dMode );
			}
		}
	}

	return E_INVALIDARG;
}
Esempio n. 13
0
static krb5_error_code KRB5_CALLCONV
kinit_prompter(krb5_context context,
               void *data,
               const char *name,
               const char *banner,
               int num_prompts,
               krb5_prompt prompts[])
{
    int i;
    k5_kinit_task * kt;
    khm_size ncp;
    krb5_error_code code = 0;
    BOOL new_prompts = TRUE;
    khm_handle csp_prcache = NULL;

    kt = (k5_kinit_task *) data;
    assert(kt && kt->magic == K5_KINIT_TASK_MAGIC);

    EnterCriticalSection(&kt->cs);

    if (kt->state == K5_KINIT_STATE_ABORTED) {
        LeaveCriticalSection(&kt->cs);
        return KRB5_LIBOS_PWDINTR;
    }

#ifdef DEBUG
    assert(kt->state == K5_KINIT_STATE_INCALL ||
           kt->state == K5_KINIT_STATE_CONFIRM);

    _reportf(L"k5_kinit_prompter() received %d prompts with name=[%S] banner=[%S]",
             num_prompts,
             name, banner);
    for (i=0; i < num_prompts; i++) {
        _reportf(L"Prompt[%d]: string[%S]", i, prompts[i].prompt);
    }
#endif

    /* we got prompts?  Then we assume that the principal is valid */

    if (!kt->is_valid_principal) {
        kt->is_valid_principal = TRUE;

        /* if the flags that were used to call kinit were restricted
           because we didn't know the validity of the principal, then
           we need to go back and retry the call with the correct
           flags. */
        if (kt->params.forwardable ||
            kt->params.proxiable ||
            kt->params.renewable) {

            _reportf(L"Retrying kinit call due to restricted flags on first call.");
            kt->state = K5_KINIT_STATE_RETRY;
            LeaveCriticalSection(&kt->cs);

            return KRB5_LIBOS_PWDINTR;
        }
    }

    /* check if we are already showing the right prompts */
    khui_cw_get_prompt_count(kt->nc, &ncp);

    if (num_prompts != (int) ncp && num_prompts != 0)
        goto _show_new_prompts;

    for (i=0; i < num_prompts; i++) {
        wchar_t wprompt[KHUI_MAXCCH_PROMPT];
        khui_new_creds_prompt * p;

        if(prompts[i].prompt) {
            AnsiStrToUnicode(wprompt, sizeof(wprompt),
                             prompts[i].prompt);
        } else {
            wprompt[0] = L'\0';
        }

        if (KHM_FAILED(khui_cw_get_prompt(kt->nc, i, &p)))
            break;

        if (                    /* if we received a prompt string,
                                   then it should be the same as the
                                   one that is displayed */
            (wprompt[0] != L'\0' &&
             (p->prompt == NULL ||
              wcscmp(wprompt, p->prompt))) ||

                                /* if we didn't receive one, then
                                   there shouldn't be one displayed.
                                   This case really shouldn't happen
                                   in reality, but we check anyway. */
            (wprompt[0] == L'\0' &&
             p->prompt != NULL) ||

                                /* the type should match */
            (prompts[i].type != p->type) ||

                                /* if this prompt should be hidden,
                                   then it must also be so */
            (prompts[i].hidden &&
             !(p->flags & KHUI_NCPROMPT_FLAG_HIDDEN)) ||
            (!prompts[i].hidden &&
             (p->flags & KHUI_NCPROMPT_FLAG_HIDDEN))
            )

            break;
    }

    if (i >= num_prompts) {

        new_prompts = FALSE;

        /* ok. looks like we are already showing the same set of
           prompts that we were supposed to show.  Sync up the values
           and go ahead. */
        goto _process_prompts;
    }

 _show_new_prompts:
    if (num_prompts == 0) {

        assert(FALSE);

        khui_cw_notify_identity_state(kt->nc,
                                      kt->nct->hwnd_panel,
                                      NULL,
                                      KHUI_CWNIS_READY |
                                      KHUI_CWNIS_NOPROGRESS |
                                      KHUI_CWNIS_VALIDATED, 0);

        code = 0;
        kt->is_null_password = TRUE;
        goto _process_prompts;
    }

    /* in addition to showing new prompts, we also cache the first set
       of prompts. */
    if (kt->prompt_set_index == 0) {
        khm_handle csp_idconfig = NULL;
        khm_handle csp_idk5 = NULL;

        kcdb_identity_get_config(kt->identity,
                                 KHM_FLAG_CREATE,
                                 &csp_idconfig);

        if (csp_idconfig != NULL)
            khc_open_space(csp_idconfig,
                           CSNAME_KRB5CRED,
                           KHM_FLAG_CREATE,
                           &csp_idk5);

        if (csp_idk5 != NULL)
            khc_open_space(csp_idk5,
                           CSNAME_PROMPTCACHE,
                           KHM_FLAG_CREATE,
                           &csp_prcache);

        khc_close_space(csp_idconfig);
        khc_close_space(csp_idk5);
    }

    {
        wchar_t wbanner[KHUI_MAXCCH_BANNER];
        wchar_t wname[KHUI_MAXCCH_PNAME];

        if(banner)
            AnsiStrToUnicode(wbanner, sizeof(wbanner), banner);
        else
            wbanner[0] = L'\0';

        if(name)
            AnsiStrToUnicode(wname, sizeof(wname), name);
        else
            LoadString(hResModule, IDS_PNAME_PW, wname, ARRAYLENGTH(wname));

        khui_cw_clear_prompts(kt->nc);

        khui_cw_begin_custom_prompts(kt->nc, num_prompts, wbanner, wname);

        if (csp_prcache) {
            FILETIME current;
            FILETIME lifetime;
            FILETIME expiry;
            khm_int64 iexpiry;
            khm_int32 t = 0;

            khc_write_string(csp_prcache, L"Banner", wbanner);
            khc_write_string(csp_prcache, L"Name", (name)? wname: L"");
            khc_write_int32(csp_prcache, L"PromptCount", (khm_int32) num_prompts);

            GetSystemTimeAsFileTime(&current);
#ifdef USE_PROMPT_CACHE_LIFETIME
            khc_read_int32(csp_params, L"PromptCacheLifetime", &t);
            if (t == 0)
                t = 172800;         /* 48 hours */
#else
            khc_read_int32(csp_params, L"MaxRenewLifetime", &t);
            if (t == 0)
                t = 2592000;    /* 30 days */
            t += 604800;        /* + 7 days */
#endif
            TimetToFileTimeInterval(t, &lifetime);
            expiry = FtAdd(&current, &lifetime);
            iexpiry = FtToInt(&expiry);

            khc_write_int64(csp_prcache, L"ExpiresOn", iexpiry);
        }
    }

    for(i=0; i < num_prompts; i++) {
        wchar_t wprompt[KHUI_MAXCCH_PROMPT];

        if(prompts[i].prompt) {
            AnsiStrToUnicode(wprompt, sizeof(wprompt),
                             prompts[i].prompt);
        } else {
            wprompt[0] = 0;
        }

        khui_cw_add_prompt(kt->nc, prompts[i].type,
                           wprompt, NULL,
                           (prompts[i].hidden?KHUI_NCPROMPT_FLAG_HIDDEN:0));

        if (csp_prcache) {
            khm_handle csp_p = NULL;
            wchar_t wnum[8];    /* should be enough for 10
                                   million prompts */

            wnum[0] = 0;
            StringCbPrintf(wnum, sizeof(wnum), L"%d", i);

            khc_open_space(csp_prcache, wnum, KHM_FLAG_CREATE, &csp_p);

            if (csp_p) {
                khc_write_string(csp_p, L"Prompt", wprompt);
                khc_write_int32(csp_p, L"Type", prompts[i].type);
                khc_write_int32(csp_p, L"Flags",
                                (prompts[i].hidden?
                                 KHUI_NCPROMPT_FLAG_HIDDEN:0));

                khc_close_space(csp_p);
            }
        }
    }

    if (csp_prcache) {
        khc_close_space(csp_prcache);
        csp_prcache = NULL;
    }

 _process_prompts:
    if (new_prompts) {
        kt->state = K5_KINIT_STATE_WAIT;

        kcdb_identity_set_flags(kt->identity,
                                KCDB_IDENT_FLAG_VALID | KCDB_IDENT_FLAG_KEY_EXPORT,
                                KCDB_IDENT_FLAG_VALID | KCDB_IDENT_FLAG_KEY_EXPORT);
        khui_cw_notify_identity_state(kt->nc, kt->nct->hwnd_panel, L"",
                                      KHUI_CWNIS_VALIDATED |
                                      KHUI_CWNIS_READY, 0);

        SetEvent(kt->h_parent_wait);
        LeaveCriticalSection(&kt->cs);
        WaitForSingleObject(kt->h_task_wait, INFINITE);
        EnterCriticalSection(&kt->cs);
    }

    /* we get here after the user selects an action that either
       cancels the credentials acquisition operation or triggers the
       actual acquisition of credentials. */
    if (kt->state != K5_KINIT_STATE_INCALL &&
        kt->state != K5_KINIT_STATE_CONFIRM) {
        code = KRB5_LIBOS_PWDINTR;
        goto _exit;
    }

    kt->is_null_password = FALSE;

    /* otherwise, we need to get the data back from the UI and return
       0 */

    khui_cw_sync_prompt_values(kt->nc);

    for(i=0; i<num_prompts; i++) {
        krb5_data * d;
        wchar_t wbuf[512];
        khm_size cbbuf;
        size_t cch;

        d = prompts[i].reply;

        cbbuf = sizeof(wbuf);
        if(KHM_SUCCEEDED(khui_cw_get_prompt_value(kt->nc, i, wbuf, &cbbuf))) {
            UnicodeStrToAnsi(d->data, d->length, wbuf);
            if(SUCCEEDED(StringCchLengthA(d->data, d->length, &cch)))
                d->length = (unsigned int) cch;
            else
                d->length = 0;
        } else {
            assert(FALSE);
            d->length = 0;
        }

        if (prompts[i].type == KRB5_PROMPT_TYPE_PASSWORD &&
            d->length == 0)

            kt->is_null_password = TRUE;
    }

    if (khui_cw_get_persist_private_data(kt->nc) &&
        num_prompts == 1 &&
	prompts[0].type == KRB5_PROMPT_TYPE_PASSWORD &&
        prompts[0].reply->length != 0) {
        k5_reply_to_acqpriv_id_request(kt->nc, prompts[0].reply);
    }

 _exit:

    kt->prompt_set_index++;

    LeaveCriticalSection(&kt->cs);

    /* entering a NULL password is equivalent to cancelling out */
    if (kt->is_null_password)
        return KRB5_LIBOS_PWDINTR;
    else
        return code;
}