// Triangulate an unimonotone chain.
bool TriangulateMonotone(Vertex *first, Vertex *last,
                         SkTDArray<SkPoint> *triangles) {
    DebugPrintf("TriangulateMonotone()\n");

    size_t numVertices = CountVertices(first, last);
    if (numVertices == kMaxCount) {
        FailureMessage("Way too many vertices: %d:\n", numVertices);
        PrintLinkedVertices(numVertices, first);
        return false;
    }

    Vertex *start = first;
    // First find the point with the smallest Y.
    DebugPrintf("TriangulateMonotone: finding bottom\n");
    int count = kMaxCount;    // Maximum number of vertices.
    for (Vertex *v = first->next(); v != first && count-- > 0; v = v->next())
        if (v->point() < start->point())
            start = v;
    if (count <= 0) {
        FailureMessage("TriangulateMonotone() was given disjoint chain\n");
        return false;   // Something went wrong.
    }

    // Start at the far end of the long edge.
    if (start->prev()->point() < start->next()->point())
        start = start->next();

    Vertex *current = start->next();
    while (numVertices >= 3) {
        if (current->angleIsConvex()) {
            DebugPrintf("Angle %p is convex\n", current);
            // Print the vertices
            PrintLinkedVertices(numVertices, start);

            appendTriangleAtVertex(current, triangles);
            if (triangles->count() > kMaxCount * 3) {
                FailureMessage("An extraordinarily large number of triangles "
                               "were generated\n");
                return false;
            }
            Vertex *save = current->prev();
            current->delink();
            current = (save == start || save == start->prev()) ? start->next()
                                                               : save;
            --numVertices;
        } else {
            if (numVertices == 3) {
                FailureMessage("Convexity error in TriangulateMonotone()\n");
                appendTriangleAtVertex(current, triangles);
                return false;
            }
            DebugPrintf("Angle %p is concave\n", current);
            current = current->next();
        }
    }
    return true;
}
bool ActiveTrapezoids::insertNewTrapezoid(Vertex *vt,
                                          Vertex *left,
                                          Vertex *right) {
    DebugPrintf("Inserting a trapezoid...");
    if (vt->fTrap0.left() == NULL && vt->fTrap0.right() == NULL) {
        vt->fTrap0.setLeft(left);
        vt->fTrap0.setRight(right);
        insert(&vt->fTrap0);
    } else if (vt->fTrap1.left() == NULL && vt->fTrap1.right() == NULL) {
        DebugPrintf("a second one...");
        vt->fTrap1.setLeft(left);
        vt->fTrap1.setRight(right);
        if (vt->fTrap1 < vt->fTrap0) {  // Keep trapezoids sorted.
            remove(&vt->fTrap0);
            Trapezoid t = vt->fTrap0;
            vt->fTrap0 = vt->fTrap1;
            vt->fTrap1 = t;
            insert(&vt->fTrap0);
        }
        insert(&vt->fTrap1);
    } else {
        FailureMessage("More than 2 trapezoids requested for a vertex\n");
        return false;
    }
    DebugPrintf(" done. %d incomplete trapezoids\n", fTrapezoids.count());
    return true;
}
static void PrintLinkedVertices(size_t n, Vertex *vertices) {
    DebugPrintf("%d vertices:\n", n);
    Vertex *v;
    for (v = vertices; n-- != 0; v = v->next())
        DebugPrintf("   (%.7g, %.7g)\n", v->point().fX, v->point().fY);
    if (v != vertices)
        FailureMessage("Vertices are not in a linked chain\n");
}
static size_t CountVertices(const Vertex *first, const Vertex *last) {
    DebugPrintf("Counting vertices: ");
    size_t count = 1;
    for (; first != last; first = first->next()) {
        ++count;
        SkASSERT(count <= kMaxCount);
        if (count >= kMaxCount) {
            FailureMessage("Vertices do not seem to be in a linked chain\n");
            break;
        }
    }
    return count;
}
// Enhance the polygon with trapezoids.
bool ConvertPointsToVertices(size_t numPts, const SkPoint *pts, Vertex *vta) {
    DebugPrintf("ConvertPointsToVertices()\n");

    // Clear everything.
    DebugPrintf("Zeroing vertices\n");
    sk_bzero(vta, numPts * sizeof(*vta));

    // Initialize vertices.
    DebugPrintf("Initializing vertices\n");
    SetVertexPoints(numPts, pts, vta);
    InitializeVertexTopology(numPts, vta);

    PrintVertices(numPts, vta);

    SkTDArray<VertexPtr> vtptr;
    vtptr.setCount(numPts);
    for (int i = numPts; i-- != 0;)
        vtptr[i].vt = vta + i;
    PrintVertexPtrs(vtptr.count(), vtptr.begin(), vta);
    DebugPrintf("Sorting vertrap ptr array [%d] %p %p\n", vtptr.count(),
        &vtptr[0], &vtptr[vtptr.count() - 1]
    );
//  SkTHeapSort(vtptr.begin(), vtptr.count());
    BubbleSort(vtptr.begin(), vtptr.count());
    DebugPrintf("Done sorting\n");
    PrintVertexPtrs(vtptr.count(), vtptr.begin(), vta);

    DebugPrintf("Traversing sorted vertrap ptrs\n");
    ActiveTrapezoids incompleteTrapezoids;
    for (VertexPtr *vtpp = vtptr.begin(); vtpp < vtptr.end(); ++vtpp) {
        DebugPrintf("%d: sorted vertrap %d\n",
                    vtpp - vtptr.begin(), vtpp->vt - vta);
        Vertex *vt = vtpp->vt;
        Vertex *e0, *e1;
        Trapezoid *t;
        switch (vt->classify(&e0, &e1)) {
            case Vertex::MONOTONE:
            monotone:
                DebugPrintf("MONOTONE %d %d\n", e0 - vta, e1 - vta);
                // We should find one edge.
                t = incompleteTrapezoids.getTrapezoidWithEdge(e0);
                if (t == NULL) {      // One of the edges is flat.
                    DebugPrintf("Monotone: cannot find a trapezoid with e0: "
                                "trying convex\n");
                    goto convex;
                }
                t->setBottom(vt);     // This trapezoid is now complete.
                incompleteTrapezoids.remove(t);

                if (e0 == t->left())  // Replace the left edge.
                    incompleteTrapezoids.insertNewTrapezoid(vt, e1, t->right());
                else                  // Replace the right edge.
                    incompleteTrapezoids.insertNewTrapezoid(vt, t->left(), e1);
                break;

            case Vertex::CONVEX:      // Start of a new trapezoid.
            convex:
                // We don't expect to find any edges.
                DebugPrintf("CONVEX %d %d\n", e0 - vta, e1 - vta);
                if (incompleteTrapezoids.withinActiveTrapezoid(
                        vt->point(), &t)) {
                    // Complete trapezoid.
                    SkASSERT(t != NULL);
                    t->setBottom(vt);
                    incompleteTrapezoids.remove(t);
                    // Introduce two new trapezoids.
                    incompleteTrapezoids.insertNewTrapezoid(vt, t->left(), e0);
                    incompleteTrapezoids.insertNewTrapezoid(vt, e1, t->right());
                } else {
                    // Insert a new trapezoid.
                    incompleteTrapezoids.insertNewTrapezoid(vt, e0, e1);
                }
                break;

            case Vertex::CONCAVE:   // End of a trapezoid.
                DebugPrintf("CONCAVE %d %d\n", e0 - vta, e1 - vta);
                // We should find two edges.
                t = incompleteTrapezoids.getTrapezoidWithEdge(e0);
                if (t == NULL) {
                    DebugPrintf("Concave: cannot find a trapezoid with e0: "
                                " trying monotone\n");
                    goto monotone;
                }
                SkASSERT(t != NULL);
                if (e0 == t->left() && e1 == t->right()) {
                    DebugPrintf(
                            "Concave edges belong to the same trapezoid.\n");
                    // Edges belong to the same trapezoid.
                    // Complete trapezoid & transfer it from the active list.
                    t->setBottom(vt);
                    incompleteTrapezoids.remove(t);
                } else {  // Edges belong to different trapezoids
                    DebugPrintf(
                            "Concave edges belong to different trapezoids.\n");
                    // Complete left and right trapezoids.
                    Trapezoid *s = incompleteTrapezoids.getTrapezoidWithEdge(
                                                                            e1);
                    if (s == NULL) {
                        DebugPrintf(
                                "Concave: cannot find a trapezoid with e1: "
                                " trying monotone\n");
                        goto monotone;
                    }
                    t->setBottom(vt);
                    s->setBottom(vt);
                    incompleteTrapezoids.remove(t);
                    incompleteTrapezoids.remove(s);

                    // Merge the two trapezoids into one below this vertex.
                    incompleteTrapezoids.insertNewTrapezoid(vt, t->left(),
                                                                s->right());
                }
                break;
        }
    }

    RemoveDegenerateTrapezoids(numPts, vta);

    DebugPrintf("Done making trapezoids\n");
    PrintVertexPtrs(vtptr.count(), vtptr.begin(), vta);

    size_t k = incompleteTrapezoids.count();
    if (k > 0) {
        FailureMessage("%d incomplete trapezoids\n", k);
        return false;
    }
    return true;
}
Пример #6
0
int
_cdecl
main(
    int argc,
    char *argv[]
    )
{
    NTSTATUS NtStatus;

    HKEY hKey;

    WCHAR UnicodeDomainName[ 32 ];
    WCHAR UnicodePassword[ 32 ];
    DWORD cbUnicodePassword = sizeof( UnicodePassword );
    DWORD cbUnicodeDomainName = sizeof( UnicodeDomainName );

    DWORD dwType;
    DWORD rc;

    ACCESS_MASK         DesiredAccess;
    LSA_HANDLE          PolicyHandle = NULL;

    PPOLICY_PRIMARY_DOMAIN_INFO PrimaryDomainInfo = NULL;

    LSA_ENUMERATION_HANDLE      TrustEnumContext = 0;
    PLSA_TRUST_INFORMATION      TrustEnumBuffer = NULL;
    DWORD                       TrustEnumCount = 0;

    //
    // Get computer name as the password to use.
    //

    if (!GetComputerNameW( UnicodePassword, &cbUnicodePassword )) {
        fprintf( stderr, "NETJOIN: Unable to read computer name from registry - %u\n", GetLastError() );
        exit( 1 );
        }

    if ((rc = RegOpenKeyW( HKEY_LOCAL_MACHINE,
                           L"System\\CurrentControlSet\\Services\\LanmanWorkstation\\Parameters",
                           &hKey
                         )
        ) ||
        (rc = RegQueryValueExW( hKey,
                                L"Domain",
                                NULL,
                                &dwType,
                                (LPBYTE)UnicodeDomainName,
                                &cbUnicodeDomainName
                              )
        )
       ) {
        fprintf( stderr, "NETJOIN: Unable to read domain name from registry - %u\n", rc );
        exit( 1 );
        }

    DesiredAccess = POLICY_VIEW_LOCAL_INFORMATION |
                        // needed to read domain info and trusted account info
                    POLICY_TRUST_ADMIN |
                        // needed to add and delete trust accounts
                    POLICY_CREATE_SECRET ;
                        // needed to add and delete secret

    NtStatus = OpenAndVerifyLSA( &PolicyHandle,
                                 DesiredAccess,
                                 UnicodeDomainName,
                                 &PrimaryDomainInfo
                               );

    if (!NT_SUCCESS( NtStatus )) {
        fprintf( stderr, "NETJOIN: Unable to read domain name from registry - %u\n", GetLastError() );
        exit( 1 );
        }

    //
    // now the domain names match and the PrimaryDomainInfo has the SID of the
    // domain, we can add trust entry and secret in LSA for this domain.
    // Before adding this, clean up old entries.
    //

    for(;;) {

        DWORD i;
        PLSA_TRUST_INFORMATION  TrustedDomainAccount;

        NtStatus = LsaEnumerateTrustedDomains( PolicyHandle,
                                               &TrustEnumContext,
                                               (PVOID *)&TrustEnumBuffer,
                                               TRUST_ENUM_PERF_BUF_SIZE,
                                               &TrustEnumCount
                                             );

        if (NtStatus == STATUS_NO_MORE_ENTRIES) {

            //
            // we are done
            //

            break;
            }

        if (NtStatus != STATUS_MORE_ENTRIES) {
            if (!NT_SUCCESS( NtStatus )) {
                FailureMessage( "LsaEnumerateTrustedDomains", NtStatus );
                goto Cleanup;
                }
            }

        //
        // delete trusted accounts and the corresponding secrets
        //

        for( i = 0, TrustedDomainAccount = TrustEnumBuffer;
                    i < TrustEnumCount;
                        TrustedDomainAccount++, i++ ) {

            NtStatus = DeleteATrustedDomain( PolicyHandle,
                                             TrustedDomainAccount
                                           );

            if (!NT_SUCCESS( NtStatus )) {
                FailureMessage( "DeleteATrustedDomain", NtStatus );
                goto Cleanup;
                }
            }

        if (NtStatus != STATUS_MORE_ENTRIES) {

            //
            // we have cleaned up all old entries.
            //

            break;
            }

        //
        // free up used enum buffer
        //

        if (TrustEnumBuffer != NULL) {
            LsaFreeMemory( TrustEnumBuffer );
            TrustEnumBuffer = NULL;
            }
        }

    //
    // add a new trust for the specified domain
    //

    NtStatus = AddATrustedDomain( PolicyHandle,
                                  (PLSA_TRUST_INFORMATION) PrimaryDomainInfo,
                                  UnicodePassword
                                );
    if (!NT_SUCCESS( NtStatus )) {
        FailureMessage( "AddATrustedDomain", NtStatus );
        }
    else {
        //
        // Give LSA a chance to do its thing.
        //

        Sleep( 10000 );
        }

Cleanup:

    if (PrimaryDomainInfo != NULL) {
        LsaFreeMemory( PrimaryDomainInfo );
        }

    if (TrustEnumBuffer != NULL) {
        LsaFreeMemory( TrustEnumBuffer );
        }

    if (PolicyHandle != NULL) {
        LsaClose( PolicyHandle );
        }

    if (NT_SUCCESS( NtStatus )) {
        fprintf( stderr,
                 "NETJOIN: Computer == '%ws' joined the '%ws' domain.\n",
                 UnicodePassword,
                 UnicodeDomainName
               );
        return 0;
        }
    else {
        fprintf( stderr,
                 "NETJOIN: Computer == '%ws' unable to join the '%ws' domain - Status == %08x\n",
                 UnicodePassword,
                 UnicodeDomainName,
                 NtStatus
               );
        return 1;
        }
}