“Loss of information”

I’ve always wondered (and again two days ago) what “irreversible loss of information” is being referd to when you reset a local user password from the “Computer Management” console.  Independantly, I’ve been tracking down a bug reported by one PMG Connect user in which the connection routine fails.

These things are linked.  The bug was a call to cryptography API CryptAquireContext failing with error NTE_BAD_KEY_STATE.  (Ok, I admit, if the software was reporting faults better, this could have been determined ages ago.)  In short, it was attempting to open a key container that existed but couldn’t be used because the user had reset the password.  Checkin the web, this occurs with a lot of software (one suggested work-around was to create a new user account!).

So, that’s some of what loss of information occurs.  To fix this problem, the software attempts to open key containers with different names when that error is encounted.

Block Sock Block

WinHttpGetProxyForUrl also blocks.  This is despite the documentation saying that it won’t if you close the handle during it’s operation.  (Let’s face it, Microsoft programmers often have a very loose sense of the meaning of block, what’s a minute or two.)  Anyway, this called for a generic class for blocking things (see previous post re gethostbyname and getaddrinfo blocking).  Anyway, the class (as before Thread is a pretty basic personal thread class):

class CAbortableAction : public Thread
{
public:
    CAbortableAction() : m_abort(CreateEvent(0,TRUE,FALSE,0),0,CloseHandle) {}
    virtual void AbortAction() {SetEvent(m_abort);}
protected:
    virtual bool StartAction()
    {
        ResetEvent(m_abort);
        if(!Create().Valid())
            return false;
        HANDLE handles[] = {ThreadHandle(),m_abort};
        return (
            WaitForMultipleObjects(sizeof(handles)/sizeof(handles[0]),
                    handles,FALSE,INFINITE)=WAIT_OBJECT_0);
    }
    virtual void DoAction() = 0;
    bool IsAborted() { return EventHandle(m_abort).IsSet();}
private:
    auto_HANDLE m_abort;
    DWORD ThreadProc() {DoAction();return 0;}
};