Exemple #1
0
VOID
WSAAPI
WsSockDelete(IN PWSSOCKET Socket)
{
    /* Check if we have a catalog entry */
    if (Socket->CatalogEntry)
    {
        /* Dereference it */
        WsTcEntryDereference(Socket->CatalogEntry);
        Socket->CatalogEntry = NULL;
    }
}
Exemple #2
0
VOID
WSAAPI
WsTcDelete(IN PTCATALOG Catalog)
{
    PLIST_ENTRY Entry;
    PTCATALOG_ENTRY CatalogEntry;

    /* Check if we're initialized */
    if (!Catalog->ProtocolList.Flink) return;

    /* Acquire lock */
    WsTcLock();

    /* Loop every entry */
    Entry = Catalog->ProtocolList.Flink;
    while (Entry != &Catalog->ProtocolList)
    {
        /* Get this entry */
        CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);

        /* Remove it */
        WsTcRemoveCatalogItem(Catalog, CatalogEntry);

        /* Dereference it */
        WsTcEntryDereference(CatalogEntry);

        /* Move to the next entry */
        Entry = Catalog->ProtocolList.Flink;
    }

    /* Check if the catalog key is opened */
    if (Catalog->CatalogKey)
    {
        /* Close it */
        RegCloseKey(Catalog->CatalogKey);
        Catalog->CatalogKey = NULL;
    }

    /* Release and delete the lock */
    WsTcUnlock();
    DeleteCriticalSection((LPCRITICAL_SECTION)&Catalog->Lock);

    /* Delete the object */
    HeapFree(WsSockHeap, 0, Catalog);
}
Exemple #3
0
/*
 * @implemented
 */
INT
WSAAPI
WSAStringToAddressW(IN LPWSTR AddressString,
                    IN INT AddressFamily,
                    IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
                    OUT LPSOCKADDR lpAddress,
                    IN OUT LPINT lpAddressLength)
{
    PWSPROCESS Process;
    PWSTHREAD Thread;
    INT ErrorCode, Status;
    DWORD CatalogEntryId;
    PTCATALOG Catalog;
    PTCATALOG_ENTRY CatalogEntry;
    DPRINT("WSAStringToAddressW: %S\n", AddressString);

    /* Enter prolog */
    if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
    {
        /* Leave now */
        SetLastError(ErrorCode);
        return SOCKET_ERROR;
    }

    /* Get the catalog */
    Catalog = WsProcGetTCatalog(Process);

    /* Check if we got custom protocol info */
    if (lpProtocolInfo)
    {
        /* Get the entry ID */
        CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;

        /* Get the entry associated with it */
        ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog,
                                                   CatalogEntryId,
                                                   &CatalogEntry);
    }
    else
    {
        /* Get it from the address family */
        ErrorCode = WsTcGetEntryFromAf(Catalog, AddressFamily, &CatalogEntry);
    }
    
    /* Check for success */
    if (ErrorCode == ERROR_SUCCESS)
    {
        /* Call the provider */
        Status = CatalogEntry->Provider->Service.lpWSPStringToAddress(AddressString,
                                                                      AddressFamily,
                                                                      &CatalogEntry->
                                                                      ProtocolInfo,
                                                                      lpAddress,
                                                                      lpAddressLength,
                                                                      &ErrorCode);

        /* Dereference the entry */
        WsTcEntryDereference(CatalogEntry);

        /* Check for success and return */
        if (Status == ERROR_SUCCESS) return ERROR_SUCCESS;
    }

    /* Set the error and return */
    SetLastError(ErrorCode);
    return SOCKET_ERROR;
}
Exemple #4
0
/*
 * @implemented
 */
INT
WSAAPI
WSAStringToAddressA(IN LPSTR AddressString,
                    IN INT AddressFamily,
                    IN LPWSAPROTOCOL_INFOA lpProtocolInfo,
                    OUT LPSOCKADDR lpAddress,
                    IN OUT  LPINT lpAddressLength)
{
    PWSPROCESS Process;
    PWSTHREAD Thread;
    INT ErrorCode, Status;
    DWORD CatalogEntryId;
    PTCATALOG Catalog;
    PTCATALOG_ENTRY CatalogEntry;
    LPWSTR UnicodeString;
    DWORD Length = (DWORD)strlen(AddressString) + 1;
    DPRINT("WSAStringToAddressA: %s\n", AddressString);

    /* Enter prolog */
    if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
    {
        /* Leave now */
        SetLastError(ErrorCode);
        return SOCKET_ERROR;
    }

    /* Allocate the unicode string */
    UnicodeString = HeapAlloc(WsSockHeap, 0, Length * 2);
    if (!UnicodeString)
    {
        /* No memory; fail */
        SetLastError(WSAENOBUFS);
        return SOCKET_ERROR;
    }

    /* Convert the string */
    MultiByteToWideChar(CP_ACP, 0, AddressString, -1, UnicodeString, Length);

    /* Get the catalog */
    Catalog = WsProcGetTCatalog(Process);

    /* Check if we got custom protocol info */
    if (lpProtocolInfo)
    {
        /* Get the entry ID */
        CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;

        /* Get the entry associated with it */
        ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog,
                                                   CatalogEntryId,
                                                   &CatalogEntry);
    }
    else
    {
        /* Get it from the address family */
        ErrorCode = WsTcGetEntryFromAf(Catalog, AddressFamily, &CatalogEntry);
    }
    
    /* Check for success */
    if (ErrorCode == ERROR_SUCCESS)
    {
        /* Call the provider */
        Status = CatalogEntry->Provider->Service.lpWSPStringToAddress(UnicodeString,
                                                              AddressFamily,
                                                              &CatalogEntry->
                                                              ProtocolInfo,
                                                              lpAddress,
                                                              lpAddressLength,
                                                              &ErrorCode);

        /* Dereference the entry */
        WsTcEntryDereference(CatalogEntry);

        /* Free the unicode string */
        HeapFree(WsSockHeap, 0, UnicodeString);

        /* Check for success and return */
        if (Status == ERROR_SUCCESS) return ERROR_SUCCESS;
    }
    else
    {
        /* Free the unicode string */
        HeapFree(WsSockHeap, 0, UnicodeString);
    }

    /* Set the error and return */
    SetLastError(ErrorCode);
    return SOCKET_ERROR;
}
Exemple #5
0
DWORD
WSAAPI
WsTcFindIfsProviderForSocket(IN PTCATALOG Catalog,
                             IN SOCKET Handle)
{
    PTPROVIDER Provider;
    IN SOCKET NewHandle;
    INT Error;
    DWORD OptionLength;
    PLIST_ENTRY Entry;
    WSAPROTOCOL_INFOW ProtocolInfo;
    DWORD UniqueId;
    INT ErrorCode;
    PTCATALOG_ENTRY CatalogEntry;

    /* Get the catalog lock */
    WsTcLock();

    /* Loop as long as the catalog changes */
CatalogChanged:

    /* Loop every provider */
    Entry = Catalog->ProtocolList.Flink;
    while (Entry != &Catalog->ProtocolList)
    {
        /* Get the catalog entry */
        CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);

        /* Move to the next entry */
        Entry = Entry->Flink;

        /* Skip it if it doesn't support IFS */
        if (!(CatalogEntry->ProtocolInfo.dwServiceFlags1 & XP1_IFS_HANDLES)) continue;

        /* Check if we need to load it */
        if (!(Provider = CatalogEntry->Provider))
        {
            /* Load it */
            ErrorCode = WsTcLoadProvider(Catalog, CatalogEntry);
            
            /* Skip it if we failed to load it */
            if (ErrorCode != ERROR_SUCCESS) continue;

            /* Get the provider again */
            Provider = CatalogEntry->Provider;
        }

        /* Reference the entry and get our unique id */
        InterlockedIncrement(&CatalogEntry->RefCount);
        UniqueId = Catalog->UniqueId;

        /* Release the lock now */
        WsTcUnlock();

        /* Get the catalog entry ID */
        OptionLength = sizeof(ProtocolInfo);
        ErrorCode = Provider->Service.lpWSPGetSockOpt(Handle,
                                                      SOL_SOCKET,
                                                      SO_PROTOCOL_INFOW,
                                                      (PCHAR)&ProtocolInfo,
                                                      (LPINT)&OptionLength,
                                                      &Error);

        /* Dereference the entry and check the result */
        WsTcEntryDereference(CatalogEntry);
        if (ErrorCode != ERROR_SUCCESS)
        {
            /* Lock and make sure this provider is still valid */
            WsTcLock();
            if (UniqueId == Catalog->UniqueId) continue;

            /* It changed! We need to start over */
            goto CatalogChanged;
        }

        /* Now get the IFS handle */
        NewHandle = WPUModifyIFSHandle(ProtocolInfo.dwCatalogEntryId,
                                       Handle,
                                       &Error);
        
        /* Check if the socket is invalid */
        if (NewHandle == INVALID_SOCKET) return WSAENOTSOCK;

        /* We suceeded, get out of here */
        return ERROR_SUCCESS;
    }

    /* Unrecognized socket if we get here: note, we still have the lock */
    WsTcUnlock();
    return WSAENOTSOCK;
}
Exemple #6
0
VOID
WSAAPI
WsTcUpdateProtocolList(IN PTCATALOG Catalog,
                       IN PLIST_ENTRY List)
{
    LIST_ENTRY TempList;
    PTCATALOG_ENTRY CatalogEntry, OldCatalogEntry;
    PLIST_ENTRY Entry;

    /* First move from our list to the old one */
    InsertHeadList(&Catalog->ProtocolList, &TempList);
    RemoveEntryList(&Catalog->ProtocolList);
    InitializeListHead(&Catalog->ProtocolList);

    /* Loop every item on the list */
    while (!IsListEmpty(List))
    {
        /* Get the catalog entry */
        Entry = RemoveHeadList(List);
        CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);

        /* Check if this item is already on our list */
        Entry = TempList.Flink;
        while (Entry != &TempList)
        {
            /* Get the catalog entry */
            OldCatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);
            Entry = Entry->Flink;

            /* Check if they match */
            if (CatalogEntry->ProtocolInfo.dwCatalogEntryId ==
                OldCatalogEntry->ProtocolInfo.dwCatalogEntryId)
            {
                /* We have a match, use the old item instead */
                WsTcEntryDereference(CatalogEntry);
                CatalogEntry = OldCatalogEntry;
                RemoveEntryList(&CatalogEntry->CatalogLink);

                /* Decrease the number of protocols we have */
                Catalog->ItemCount--;
                break;
            }
        }

        /* Add this item */
        InsertTailList(&Catalog->ProtocolList, &CatalogEntry->CatalogLink);
        Catalog->ItemCount++;
    }

    /* If there's anything left on the temporary list */
    while (!IsListEmpty(&TempList))
    {
        /* Get the entry */
        Entry = RemoveHeadList(&TempList);
        CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);

        /* Remove it */
        Catalog->ItemCount--;
        WsTcEntryDereference(CatalogEntry);
    }
}
Exemple #7
0
DWORD
WSAAPI
WsTcRefreshFromRegistry(IN PTCATALOG Catalog,
                        IN HANDLE CatalogEvent)
{
    INT ErrorCode;
    BOOLEAN LocalEvent = FALSE;
    LIST_ENTRY LocalList;
    DWORD UniqueId;
    HKEY EntriesKey;
    DWORD CatalogEntries;
    PTCATALOG_ENTRY CatalogEntry;
    DWORD NextCatalogEntry;
    BOOL NewChangesMade;
    PLIST_ENTRY Entry;
    DWORD RegType = REG_DWORD;
    DWORD RegSize = sizeof(DWORD);
    DWORD i;

    /* Check if we got an event */
    if (!CatalogEvent)
    {
        /* Create an event ourselves */
        CatalogEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
        if (!CatalogEvent) return WSASYSCALLFAILURE;
        LocalEvent = TRUE;
    }

    /* Lock the catalog */
    WsTcLock();

    /* Initialize our local list for the loop */
    InitializeListHead(&LocalList);

    /* Start looping */
    do
    {
        /* Setup notifications for the catalog entry */
        ErrorCode = WsSetupCatalogProtection(Catalog->CatalogKey,
                                             CatalogEvent,
                                             &UniqueId);
        if (ErrorCode != ERROR_SUCCESS) break;

        /* Check if we've changed till now */
        if (UniqueId == Catalog->UniqueId)
        {
            /* We haven't, so return */
            ErrorCode = ERROR_SUCCESS;
            break;
        }

        /* Now Open the Entries */
        ErrorCode = RegOpenKeyEx(Catalog->CatalogKey,
                                 "Catalog_Entries",
                                 0,
                                 MAXIMUM_ALLOWED,
                                 &EntriesKey);
        if (ErrorCode != ERROR_SUCCESS)
        {
            /* Critical failure */
            ErrorCode = WSASYSCALLFAILURE;
            break;
        }
        
        /* Get the next entry */
        ErrorCode = RegQueryValueEx(Catalog->CatalogKey,
                                    "Next_Catalog_Entry_ID",
                                    0,
                                    &RegType,
                                    (LPBYTE)&NextCatalogEntry,
                                    &RegSize);
        if (ErrorCode != ERROR_SUCCESS)
        {
            /* Critical failure */
            ErrorCode = WSASYSCALLFAILURE;
            break;
        }

        /* Find out how many there are */
        ErrorCode = RegQueryValueEx(Catalog->CatalogKey,
                                    "Num_Catalog_Entries",
                                    0,
                                    &RegType,
                                    (LPBYTE)&CatalogEntries,
                                    &RegSize);
        if (ErrorCode != ERROR_SUCCESS)
        {
            /* Critical failure */
            ErrorCode = WSASYSCALLFAILURE;
            break;
        }

        /* Initialize them all */
        for (i = 1; i <= CatalogEntries; i++) 
        {
            /* Allocate a Catalog Entry Structure */
            CatalogEntry = WsTcEntryAllocate();
            if (!CatalogEntry)
            {
                /* Not enough memory, fail */
                ErrorCode = WSA_NOT_ENOUGH_MEMORY;
                break;
            }

            /* Initialize it from the Registry Key */
            ErrorCode = WsTcEntryInitializeFromRegistry(CatalogEntry,
                                                        EntriesKey,
                                                        i);
            if (ErrorCode != ERROR_SUCCESS)
            {
                /* We failed to get it, dereference the entry and leave */
                WsTcEntryDereference(CatalogEntry);
                break;
            }

            /* Insert it to our List */
            InsertTailList(&LocalList, &CatalogEntry->CatalogLink);
        }

        /* Close the catalog key */
        RegCloseKey(EntriesKey);

        /* Check if we changed during our read and if we have success */
        NewChangesMade = WsCheckCatalogState(CatalogEvent);
        if (!NewChangesMade && ErrorCode == ERROR_SUCCESS)
        {
            /* All is good, update the protocol list */
            WsTcUpdateProtocolList(Catalog, &LocalList);

            /* Update and return */
            Catalog->UniqueId = UniqueId;
            Catalog->NextId = NextCatalogEntry;
            break;
        }

        /* We failed and/or catalog data changed, free what we did till now */
        while (!IsListEmpty(&LocalList))
        {
            /* Get the LP Catalog Item */
            Entry = RemoveHeadList(&LocalList);
            CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);

            /* Dereference it */
            WsTcEntryDereference(CatalogEntry);
        }
    } while (NewChangesMade);

    /* Release the lock */
    WsTcUnlock();

    /* Close the event, if any was created by us */
    if (LocalEvent) CloseHandle(CatalogEvent);

    /* All Done */
    return ErrorCode;
}
Exemple #8
0
/*
 * @implemented
 */
SOCKET
WSAAPI
WSASocketW(IN INT af,
           IN INT type,
           IN INT protocol,
           IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
           IN GROUP g,
           IN DWORD dwFlags)
{
    PWSPROCESS Process;
    PWSTHREAD Thread;
    INT ErrorCode;
    PTCATALOG Catalog;
    DWORD CatalogId;
    PTCATALOG_ENTRY CatalogEntry;
    LPWSAPROTOCOL_INFOW ProtocolInfo;
    DWORD OpenType;
    SOCKET Status = INVALID_SOCKET;
    DPRINT("WSASocketW: %lx, %lx, %lx, %p\n", af, type, protocol, lpProtocolInfo);

    /* Enter prolog */
    if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
    {
        /* Fail now */
        SetLastError(ErrorCode);
        return INVALID_SOCKET;
    }

    /* Get the catalog */
    Catalog = WsProcGetTCatalog(Process);

    /* Find a Provider for the Catalog ID */
    if (lpProtocolInfo)
    {
        /* Get the catalog ID */
        CatalogId = lpProtocolInfo->dwCatalogEntryId;

        /* Get the Catalog Entry */
        ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog,
                    CatalogId,
                    &CatalogEntry);
    }
    else
    {
        /* No ID */
        CatalogId = 0;

DoLookup:
        /* Get the Catalog Data from the Socket Info */
        ErrorCode = WsTcGetEntryFromTriplet(Catalog,
                                            af,
                                            type,
                                            protocol,
                                            CatalogId,
                                            &CatalogEntry);
    }

    /* Check for Success */
    if (ErrorCode == ERROR_SUCCESS)
    {
        /* Use the default Protocol Info if none given */
        ProtocolInfo = lpProtocolInfo ? lpProtocolInfo : &CatalogEntry->ProtocolInfo;

        /* Save the open type and set new one */
        OpenType = Thread->OpenType;
        Thread->OpenType = (dwFlags & WSA_FLAG_OVERLAPPED) ?
                           0 : SO_SYNCHRONOUS_NONALERT;

        /* Call the Provider to create the Socket */
        Status = CatalogEntry->Provider->Service.lpWSPSocket(af,
                 type,
                 protocol,
                 ProtocolInfo,
                 g,
                 dwFlags,
                 &ErrorCode);
        /* Restore open type */
        Thread->OpenType = OpenType;

        /* Get the catalog ID now, and dereference */
        CatalogId = ProtocolInfo->dwCatalogEntryId;
        WsTcEntryDereference(CatalogEntry);

        /* Did we fail with WSAEINPROGRESS and had no specific provider? */
        if ((Status == INVALID_SOCKET) &&
                (ErrorCode == WSAEINPROGRESS) &&
                !(lpProtocolInfo))
        {
            /* In that case, restart the lookup from this ID */
            goto DoLookup;
        }

        /* Check if we got a valid socket */
        if (Status != INVALID_SOCKET)
        {
            /* Add an API reference and return */
            WsSockAddApiReference(Status);
            return Status;
        }
    }

    /* Return with an Error */
    SetLastError(ErrorCode);
    return INVALID_SOCKET;
}
Exemple #9
0
/*
 * @implemented
 */
SOCKET
WSPAPI
WPUModifyIFSHandle(IN DWORD dwCatalogEntryId,
                   IN SOCKET ProposedHandle,
                   OUT LPINT lpErrno)
{
    SOCKET Handle = INVALID_SOCKET;
    DWORD ErrorCode = ERROR_SUCCESS;
    PWSPROCESS Process;
    PTCATALOG Catalog;
    PTCATALOG_ENTRY Entry;
    PWSSOCKET Socket;
    DPRINT("WPUModifyIFSHandle: %lx, %lx\n", dwCatalogEntryId, ProposedHandle);

    /* Get the current process */
    if ((Process = WsGetProcess()))
    {
        /* Get the Transport Catalog */
        if ((Catalog = WsProcGetTCatalog(Process)))
        {
            /* Get the entry for this ID */
            ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog,
                        dwCatalogEntryId,
                        &Entry);
            /* Check for success */
            if (ErrorCode == ERROR_SUCCESS)
            {
                /* Create a socket object */
                if ((Socket = WsSockAllocate()))
                {
                    /* Initialize it */
                    WsSockInitialize(Socket, Entry);

                    /* Associate it */
                    ErrorCode = WsSockAssociateHandle(Socket,
                                                      ProposedHandle,
                                                      TRUE);
                    /* Check for success */
                    if (ErrorCode == ERROR_SUCCESS)
                    {
                        /* Return */
                        Handle = ProposedHandle;
                        *lpErrno = ERROR_SUCCESS;
                    }
                    else
                    {
                        /* Fail */
                        WsSockDereference(Socket);
                        *lpErrno = ErrorCode;
                    }

                    /* Dereference the extra count */
                    WsSockDereference(Socket);
                }
                else
                {
                    /* No memory to allocate a socket */
                    *lpErrno = WSAENOBUFS;
                }

                /* Dereference the catalog entry */
                WsTcEntryDereference(Entry);
            }
            else
            {
                /* Entry not found */
                *lpErrno = ErrorCode;
            }
        }
        else
        {
            /* Catalog not found */
            *lpErrno = WSANOTINITIALISED;
        }
    }
    else
    {
        /* Process not ready */
        *lpErrno = WSANOTINITIALISED;
    }

    /* Return */
    return Handle;
}